Browse Source

ref(ddm): Move MetricSearchBar to own file (#62921)

ArthurKnaus 1 year ago
parent
commit
2f4b01c2e2

+ 1 - 1
static/app/views/alerts/rules/metric/ruleConditionsForm.tsx

@@ -38,7 +38,7 @@ import {
   DATA_SOURCE_TO_SET_AND_EVENT_TYPES,
 } from 'sentry/views/alerts/utils';
 import {AlertType, getSupportedAndOmittedTags} from 'sentry/views/alerts/wizard/options';
-import {MetricSearchBar} from 'sentry/views/ddm/queryBuilder';
+import {MetricSearchBar} from 'sentry/views/ddm/metricSearchBar';
 
 import {getProjectOptions} from '../utils';
 

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

@@ -4,7 +4,7 @@ import {SearchBarProps} from 'sentry/components/events/searchBar';
 import {PageFilters} from 'sentry/types';
 import {getMRI} from 'sentry/utils/metrics/mri';
 import {WidgetQuery} from 'sentry/views/dashboards/types';
-import {MetricSearchBar as DDMSearchBar} from 'sentry/views/ddm/queryBuilder';
+import {MetricSearchBar as DDMSearchBar} from 'sentry/views/ddm/metricSearchBar';
 
 interface Props {
   onClose: SearchBarProps['onClose'];

+ 122 - 0
static/app/views/ddm/metricSearchBar.tsx

@@ -0,0 +1,122 @@
+import {useCallback, useMemo} from 'react';
+import styled from '@emotion/styled';
+import memoize from 'lodash/memoize';
+
+import {BooleanOperator} from 'sentry/components/searchSyntax/parser';
+import SmartSearchBar, {SmartSearchBarProps} from 'sentry/components/smartSearchBar';
+import {t} from 'sentry/locale';
+import {MRI, SavedSearchType, TagCollection} from 'sentry/types';
+import {getUseCaseFromMRI} from 'sentry/utils/metrics/mri';
+import {useMetricsTags} from 'sentry/utils/metrics/useMetricsTags';
+import useApi from 'sentry/utils/useApi';
+import useOrganization from 'sentry/utils/useOrganization';
+import usePageFilters from 'sentry/utils/usePageFilters';
+
+interface MetricSearchBarProps extends Partial<SmartSearchBarProps> {
+  onChange: (value: string) => void;
+  projectIds: string[];
+  disabled?: boolean;
+  mri?: MRI;
+  query?: string;
+}
+
+const EMPTY_ARRAY = [];
+const EMPTY_SET = new Set<never>();
+const DISSALLOWED_LOGICAL_OPERATORS = new Set([BooleanOperator.OR]);
+
+export function MetricSearchBar({
+  mri,
+  disabled,
+  onChange,
+  query,
+  projectIds,
+  ...props
+}: MetricSearchBarProps) {
+  const org = useOrganization();
+  const api = useApi();
+  const {selection} = usePageFilters();
+  const projectIdNumbers = useMemo(
+    () => projectIds.map(id => parseInt(id, 10)),
+    [projectIds]
+  );
+
+  const {data: tags = EMPTY_ARRAY, isLoading} = useMetricsTags(mri, projectIdNumbers);
+
+  const supportedTags: TagCollection = useMemo(
+    () => tags.reduce((acc, tag) => ({...acc, [tag.key]: tag}), {}),
+    [tags]
+  );
+
+  const fetchTagValues = useMemo(() => {
+    const fn = memoize((tagKey: string) => {
+      // clear response from cache after 10 seconds
+      setTimeout(() => {
+        fn.cache.delete(tagKey);
+      }, 10000);
+      return api.requestPromise(`/organizations/${org.slug}/metrics/tags/${tagKey}/`, {
+        query: {
+          metric: mri,
+          useCase: getUseCaseFromMRI(mri),
+          project: selection.projects,
+        },
+      });
+    });
+    return fn;
+  }, [api, mri, org.slug, selection.projects]);
+
+  const getTagValues = useCallback(
+    async (tag: any, search: string) => {
+      const tagsValues = await fetchTagValues(tag.key);
+
+      return tagsValues
+        .filter(
+          tv =>
+            tv.value !== '' &&
+            tv.value.toLocaleLowerCase().includes(search.toLocaleLowerCase())
+        )
+        .map(tv => tv.value);
+    },
+    [fetchTagValues]
+  );
+
+  const handleChange = useCallback(
+    (value: string, {validSearch} = {validSearch: true}) => {
+      if (validSearch) {
+        onChange(value);
+      }
+    },
+    [onChange]
+  );
+
+  return (
+    <WideSearchBar
+      disabled={disabled}
+      maxMenuHeight={220}
+      organization={org}
+      onGetTagValues={getTagValues}
+      supportedTags={supportedTags}
+      // don't highlight tags while loading as we don't know yet if they are supported
+      highlightUnsupportedTags={!isLoading}
+      disallowedLogicalOperators={DISSALLOWED_LOGICAL_OPERATORS}
+      disallowFreeText
+      onClose={handleChange}
+      onSearch={handleChange}
+      placeholder={t('Filter by tags')}
+      query={query}
+      savedSearchType={SavedSearchType.METRIC}
+      durationKeys={EMPTY_SET}
+      percentageKeys={EMPTY_SET}
+      numericKeys={EMPTY_SET}
+      dateKeys={EMPTY_SET}
+      booleanKeys={EMPTY_SET}
+      sizeKeys={EMPTY_SET}
+      textOperatorKeys={EMPTY_SET}
+      {...props}
+    />
+  );
+}
+
+const WideSearchBar = styled(SmartSearchBar)`
+  width: 100%;
+  opacity: ${p => (p.disabled ? '0.6' : '1')};
+`;

+ 4 - 118
static/app/views/ddm/queryBuilder.tsx

@@ -1,21 +1,18 @@
-import {Fragment, memo, useCallback, useEffect, useMemo, useState} from 'react';
+import {Fragment, memo, useEffect, useMemo, useState} from 'react';
 import styled from '@emotion/styled';
 import * as Sentry from '@sentry/react';
-import memoize from 'lodash/memoize';
 
 import {navigateTo} from 'sentry/actionCreators/navigation';
 import {Button} from 'sentry/components/button';
 import {HeaderTitle} from 'sentry/components/charts/styles';
 import {CompactSelect} from 'sentry/components/compactSelect';
 import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
-import {BooleanOperator} from 'sentry/components/searchSyntax/parser';
-import SmartSearchBar, {SmartSearchBarProps} from 'sentry/components/smartSearchBar';
 import Tag from 'sentry/components/tag';
 import TextOverflow from 'sentry/components/textOverflow';
 import {IconLightning, IconReleases, IconSettings} from 'sentry/icons';
 import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
-import {MetricMeta, MRI, SavedSearchType, TagCollection} from 'sentry/types';
+import {MetricMeta, MRI} from 'sentry/types';
 import {
   defaultMetricDisplayType,
   getReadableMetricType,
@@ -29,14 +26,12 @@ import {
   MetricWidgetQueryParams,
   stringifyMetricWidget,
 } from 'sentry/utils/metrics';
-import {formatMRI, getUseCaseFromMRI, parseMRI} from 'sentry/utils/metrics/mri';
+import {formatMRI, parseMRI} from 'sentry/utils/metrics/mri';
 import {useMetricsMeta} from 'sentry/utils/metrics/useMetricsMeta';
 import {useMetricsTags} from 'sentry/utils/metrics/useMetricsTags';
-import useApi from 'sentry/utils/useApi';
 import useKeyPress from 'sentry/utils/useKeyPress';
-import useOrganization from 'sentry/utils/useOrganization';
-import usePageFilters from 'sentry/utils/usePageFilters';
 import useRouter from 'sentry/utils/useRouter';
+import {MetricSearchBar} from 'sentry/views/ddm/metricSearchBar';
 
 type QueryBuilderProps = {
   displayType: MetricDisplayType;
@@ -302,110 +297,6 @@ export const QueryBuilder = memo(function QueryBuilder({
   );
 });
 
-interface MetricSearchBarProps extends Partial<SmartSearchBarProps> {
-  onChange: (value: string) => void;
-  projectIds: string[];
-  disabled?: boolean;
-  mri?: MRI;
-  query?: string;
-}
-
-const EMPTY_ARRAY = [];
-const EMPTY_SET = new Set<never>();
-const DISSALLOWED_LOGICAL_OPERATORS = new Set([BooleanOperator.OR]);
-
-export function MetricSearchBar({
-  mri,
-  disabled,
-  onChange,
-  query,
-  projectIds,
-  ...props
-}: MetricSearchBarProps) {
-  const org = useOrganization();
-  const api = useApi();
-  const {selection} = usePageFilters();
-  const projectIdNumbers = useMemo(
-    () => projectIds.map(id => parseInt(id, 10)),
-    [projectIds]
-  );
-
-  const {data: tags = EMPTY_ARRAY, isLoading} = useMetricsTags(mri, projectIdNumbers);
-
-  const supportedTags: TagCollection = useMemo(
-    () => tags.reduce((acc, tag) => ({...acc, [tag.key]: tag}), {}),
-    [tags]
-  );
-
-  const fetchTagValues = useMemo(() => {
-    const fn = memoize((tagKey: string) => {
-      // clear response from cache after 10 seconds
-      setTimeout(() => {
-        fn.cache.delete(tagKey);
-      }, 10000);
-      return api.requestPromise(`/organizations/${org.slug}/metrics/tags/${tagKey}/`, {
-        query: {
-          metric: mri,
-          useCase: getUseCaseFromMRI(mri),
-          project: selection.projects,
-        },
-      });
-    });
-    return fn;
-  }, [api, mri, org.slug, selection.projects]);
-
-  const getTagValues = useCallback(
-    async (tag: any, search: string) => {
-      const tagsValues = await fetchTagValues(tag.key);
-
-      return tagsValues
-        .filter(
-          tv =>
-            tv.value !== '' &&
-            tv.value.toLocaleLowerCase().includes(search.toLocaleLowerCase())
-        )
-        .map(tv => tv.value);
-    },
-    [fetchTagValues]
-  );
-
-  const handleChange = useCallback(
-    (value: string, {validSearch} = {validSearch: true}) => {
-      if (validSearch) {
-        onChange(value);
-      }
-    },
-    [onChange]
-  );
-
-  return (
-    <WideSearchBar
-      disabled={disabled}
-      maxMenuHeight={220}
-      organization={org}
-      onGetTagValues={getTagValues}
-      supportedTags={supportedTags}
-      // don't highlight tags while loading as we don't know yet if they are supported
-      highlightUnsupportedTags={!isLoading}
-      disallowedLogicalOperators={DISSALLOWED_LOGICAL_OPERATORS}
-      disallowFreeText
-      onClose={handleChange}
-      onSearch={handleChange}
-      placeholder={t('Filter by tags')}
-      query={query}
-      savedSearchType={SavedSearchType.METRIC}
-      durationKeys={EMPTY_SET}
-      percentageKeys={EMPTY_SET}
-      numericKeys={EMPTY_SET}
-      dateKeys={EMPTY_SET}
-      booleanKeys={EMPTY_SET}
-      sizeKeys={EMPTY_SET}
-      textOperatorKeys={EMPTY_SET}
-      {...props}
-    />
-  );
-}
-
 function getWidgetDisplayType(
   mri: MetricsQuery['mri'],
   op: MetricsQuery['op']
@@ -427,11 +318,6 @@ const QueryBuilderRow = styled('div')`
   padding-bottom: 0;
 `;
 
-const WideSearchBar = styled(SmartSearchBar)`
-  width: 100%;
-  opacity: ${p => (p.disabled ? '0.6' : '1')};
-`;
-
 const WrapPageFilterBar = styled(PageFilterBar)`
   max-width: max-content;
   height: auto;