Browse Source

ref(sampling): Remove filters and sampling ui (#36504)

Priscila Oliveira 2 years ago
parent
commit
f8fe9d64a5

+ 0 - 9
static/app/routes.tsx

@@ -14,7 +14,6 @@ import {EXPERIMENTAL_SPA} from 'sentry/constants';
 import {t} from 'sentry/locale';
 import HookStore from 'sentry/stores/hookStore';
 import {HookName} from 'sentry/types/hooks';
-import {SamplingRuleType} from 'sentry/types/sampling';
 import errorHandler from 'sentry/utils/errorHandler';
 import App from 'sentry/views/app';
 import AuthLayout from 'sentry/views/auth/layout';
@@ -463,14 +462,6 @@ function buildRoutes() {
         <IndexRedirect to="data-filters/" />
         <Route path=":filterType/" />
       </Route>
-      <Route
-        path="sampling/"
-        name={t('Sampling')}
-        component={make(() => import('sentry/views/settings/project/sampling'))}
-      >
-        <IndexRedirect to={`${SamplingRuleType.TRACE}/`} />
-        <Route path=":ruleType/" />
-      </Route>
       <Route
         path="server-side-sampling/"
         name={t('Server-side Sampling')}

+ 1 - 1
static/app/views/performance/landing/samplingModal.tsx

@@ -44,7 +44,7 @@ const SamplingModal = (props: Props) => {
             {
               projectSettings: (
                 <Link
-                  to={`/settings/${organization.slug}/projects/${project?.slug}/filters-and-sampling/`}
+                  to={`/settings/${organization.slug}/projects/${project?.slug}/server-side-sampling/`}
                 />
               ),
             }

+ 0 - 47
static/app/views/settings/project/sampling/index.tsx

@@ -1,47 +0,0 @@
-import {RouteComponentProps} from 'react-router';
-
-import Access from 'sentry/components/acl/access';
-import Feature from 'sentry/components/acl/feature';
-import FeatureDisabled from 'sentry/components/acl/featureDisabled';
-import {PanelAlert} from 'sentry/components/panels';
-import {t} from 'sentry/locale';
-import {Project} from 'sentry/types';
-import {SamplingRuleType} from 'sentry/types/sampling';
-import useOrganization from 'sentry/utils/useOrganization';
-
-import {Sampling} from './sampling';
-
-type Props = RouteComponentProps<{ruleType: SamplingRuleType}, {}> & {
-  project: Project;
-};
-
-/**
- * This is will be replaced by the new Server Side Sampling UI.
- *
- * @deprecated
- */
-function Index(props: Props) {
-  const organization = useOrganization();
-
-  return (
-    <Feature
-      features={['filters-and-sampling']}
-      organization={organization}
-      renderDisabled={() => (
-        <FeatureDisabled
-          alert={PanelAlert}
-          features={['organization:filters-and-sampling']}
-          featureName={t('Sampling')}
-        />
-      )}
-    >
-      <Access organization={organization} access={['project:write']}>
-        {({hasAccess}) => (
-          <Sampling {...props} hasAccess={hasAccess} organization={organization} />
-        )}
-      </Access>
-    </Feature>
-  );
-}
-
-export default Index;

+ 0 - 217
static/app/views/settings/project/sampling/modal/conditions.tsx

@@ -1,217 +0,0 @@
-import {Fragment, useEffect, useState} from 'react';
-import styled from '@emotion/styled';
-
-import Button from 'sentry/components/button';
-import FieldRequiredBadge from 'sentry/components/forms/field/fieldRequiredBadge';
-import TextareaField from 'sentry/components/forms/textareaField';
-import {IconDelete} from 'sentry/icons/iconDelete';
-import {t} from 'sentry/locale';
-import space from 'sentry/styles/space';
-import {Project, Tag} from 'sentry/types';
-import {LegacyBrowser, SamplingInnerName} from 'sentry/types/sampling';
-import useApi from 'sentry/utils/useApi';
-
-import {
-  addCustomTagPrefix,
-  getInnerNameLabel,
-  isCustomTagName,
-  stripCustomTagPrefix,
-} from '../utils';
-
-import LegacyBrowsers from './legacyBrowsers';
-import {TagKeyAutocomplete} from './tagKeyAutocomplete';
-import {TagValueAutocomplete} from './tagValueAutocomplete';
-import {getMatchFieldPlaceholder, getTagKey} from './utils';
-
-type Condition = {
-  category: SamplingInnerName | string; // string is used for custom tags
-  legacyBrowsers?: Array<LegacyBrowser>;
-  match?: string;
-};
-
-type Props = Pick<
-  React.ComponentProps<typeof TagValueAutocomplete>,
-  'orgSlug' | 'projectId'
-> & {
-  conditions: Condition[];
-  onChange: <T extends keyof Condition>(
-    index: number,
-    field: T,
-    value: Condition[T]
-  ) => void;
-  onDelete: (index: number) => void;
-  projectSlug: Project['slug'];
-};
-
-function Conditions({
-  conditions,
-  orgSlug,
-  projectId,
-  projectSlug,
-  onDelete,
-  onChange,
-}: Props) {
-  const api = useApi();
-  const [tags, setTags] = useState<Tag[]>([]);
-
-  useEffect(() => {
-    async function fetchTags() {
-      try {
-        const response = await api.requestPromise(
-          `/projects/${orgSlug}/${projectSlug}/tags/`,
-          {query: {onlySamplingTags: 1}}
-        );
-        setTags(response);
-      } catch {
-        // Do nothing, just autocomplete won't suggest any results
-      }
-    }
-
-    fetchTags();
-  }, [api, orgSlug, projectSlug]);
-
-  return (
-    <Fragment>
-      {conditions.map((condition, index) => {
-        const {category, match, legacyBrowsers} = condition;
-        const displayLegacyBrowsers = category === SamplingInnerName.EVENT_LEGACY_BROWSER;
-        const isCustomTag = isCustomTagName(category);
-
-        const isBooleanField =
-          category === SamplingInnerName.EVENT_LOCALHOST ||
-          category === SamplingInnerName.EVENT_WEB_CRAWLERS;
-        displayLegacyBrowsers;
-
-        const isAutoCompleteField =
-          category === SamplingInnerName.EVENT_ENVIRONMENT ||
-          category === SamplingInnerName.EVENT_RELEASE ||
-          category === SamplingInnerName.EVENT_TRANSACTION ||
-          category === SamplingInnerName.EVENT_OS_NAME ||
-          category === SamplingInnerName.EVENT_DEVICE_FAMILY ||
-          category === SamplingInnerName.EVENT_DEVICE_NAME ||
-          category === SamplingInnerName.TRACE_ENVIRONMENT ||
-          category === SamplingInnerName.TRACE_RELEASE ||
-          category === SamplingInnerName.TRACE_TRANSACTION ||
-          isCustomTag;
-
-        return (
-          <ConditionWrapper key={index}>
-            <LeftCell>
-              {isCustomTag ? (
-                <TagKeyAutocomplete
-                  tags={tags}
-                  onChange={value =>
-                    onChange(index, 'category', addCustomTagPrefix(value))
-                  }
-                  value={stripCustomTagPrefix(category)}
-                  disabledOptions={conditions
-                    .filter(
-                      cond => isCustomTagName(cond.category) && cond.category !== category
-                    )
-                    .map(cond => stripCustomTagPrefix(cond.category))}
-                />
-              ) : (
-                <span>
-                  {getInnerNameLabel(category)}
-                  <FieldRequiredBadge />
-                </span>
-              )}
-            </LeftCell>
-            <CenterCell>
-              {!isBooleanField &&
-                (isAutoCompleteField ? (
-                  <TagValueAutocomplete
-                    category={category}
-                    tagKey={getTagKey(condition)}
-                    orgSlug={orgSlug}
-                    projectId={projectId}
-                    value={match}
-                    onChange={value => onChange(index, 'match', value)}
-                  />
-                ) : (
-                  <StyledTextareaField
-                    name="match"
-                    value={match}
-                    onChange={value => onChange(index, 'match', value)}
-                    placeholder={getMatchFieldPlaceholder(category)}
-                    inline={false}
-                    rows={1}
-                    autosize
-                    hideControlState
-                    flexibleControlStateSize
-                    required
-                    stacked
-                  />
-                ))}
-            </CenterCell>
-            <RightCell>
-              <Button
-                onClick={() => onDelete(index)}
-                icon={<IconDelete />}
-                aria-label={t('Delete Condition')}
-              />
-            </RightCell>
-            {displayLegacyBrowsers && (
-              <LegacyBrowsers
-                selectedLegacyBrowsers={legacyBrowsers}
-                onChange={value => {
-                  onChange(index, 'legacyBrowsers', value);
-                }}
-              />
-            )}
-          </ConditionWrapper>
-        );
-      })}
-    </Fragment>
-  );
-}
-
-export default Conditions;
-
-const ConditionWrapper = styled('div')`
-  display: grid;
-  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
-  align-items: flex-start;
-  padding: ${space(1)} ${space(2)};
-  :not(:last-child) {
-    border-bottom: 1px solid ${p => p.theme.gray100};
-  }
-
-  @media (min-width: ${p => p.theme.breakpoints.small}) {
-    grid-template-columns: minmax(0, 0.6fr) minmax(0, 1fr) max-content;
-  }
-`;
-
-const Cell = styled('div')`
-  min-height: 40px;
-  display: inline-flex;
-  align-items: center;
-`;
-
-const LeftCell = styled(Cell)`
-  padding-right: ${space(1)};
-  line-height: 16px;
-`;
-
-const CenterCell = styled(Cell)`
-  padding-top: ${space(1)};
-  grid-column: 1/-1;
-  grid-row: 2/2;
-  ${p => !p.children && 'display: none'};
-
-  @media (min-width: ${p => p.theme.breakpoints.small}) {
-    grid-column: auto;
-    grid-row: auto;
-    padding-top: 0;
-  }
-`;
-
-const RightCell = styled(Cell)`
-  justify-content: flex-end;
-  padding-left: ${space(1)};
-`;
-
-const StyledTextareaField = styled(TextareaField)`
-  padding-bottom: 0;
-  width: 100%;
-`;

+ 0 - 580
static/app/views/settings/project/sampling/modal/index.tsx

@@ -1,580 +0,0 @@
-import {Fragment, KeyboardEvent, useEffect, useState} from 'react';
-import {components, createFilter} from 'react-select';
-import styled from '@emotion/styled';
-import isEqual from 'lodash/isEqual';
-import partition from 'lodash/partition';
-
-import {addErrorMessage} from 'sentry/actionCreators/indicator';
-import {ModalRenderProps} from 'sentry/actionCreators/modal';
-import Button from 'sentry/components/button';
-import ButtonBar from 'sentry/components/buttonBar';
-import CompactSelect from 'sentry/components/forms/compactSelect';
-import NumberField from 'sentry/components/forms/numberField';
-import Option from 'sentry/components/forms/selectOption';
-import Link from 'sentry/components/links/link';
-import {Panel, PanelAlert, PanelBody, PanelHeader} from 'sentry/components/panels';
-import Truncate from 'sentry/components/truncate';
-import {IconAdd} from 'sentry/icons';
-import {IconSearch} from 'sentry/icons/iconSearch';
-import {t, tct} from 'sentry/locale';
-import space from 'sentry/styles/space';
-import {Organization, Project, SelectValue} from 'sentry/types';
-import {
-  SamplingConditionOperator,
-  SamplingInnerName,
-  SamplingRule,
-  SamplingRuleType,
-} from 'sentry/types/sampling';
-import {defined} from 'sentry/utils';
-import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
-import recreateRoute from 'sentry/utils/recreateRoute';
-import useApi from 'sentry/utils/useApi';
-import {useLocation} from 'sentry/utils/useLocation';
-import {useParams} from 'sentry/utils/useParams';
-import {useRoutes} from 'sentry/utils/useRoutes';
-import EmptyMessage from 'sentry/views/settings/components/emptyMessage';
-import TextBlock from 'sentry/views/settings/components/text/textBlock';
-
-import {getInnerNameLabel, isCustomTagName} from '../utils';
-
-import Conditions from './conditions';
-import {
-  distributedTracesConditions,
-  generateConditionCategoriesOptions,
-  getErrorMessage,
-  getNewCondition,
-  individualTransactionsConditions,
-  isLegacyBrowser,
-} from './utils';
-
-const conditionAlreadyAddedTooltip = t('This condition has already been added');
-
-type ConditionsProps = React.ComponentProps<typeof Conditions>['conditions'];
-
-type State = {
-  conditions: ConditionsProps;
-  errors: {
-    sampleRate?: string;
-  };
-  sampleRate: number | null;
-};
-
-type Props = ModalRenderProps & {
-  disabled: boolean;
-  onSubmitSuccess: (project: Project, successMessage: React.ReactNode) => void;
-  organization: Organization;
-  project: Project;
-  rules: SamplingRule[];
-  type: SamplingRuleType;
-  rule?: SamplingRule;
-};
-
-export function SamplingRuleModal({
-  Header,
-  Body,
-  Footer,
-  closeModal,
-  project,
-  onSubmitSuccess,
-  rule,
-  rules,
-  disabled,
-  type,
-  organization,
-}: Props) {
-  const api = useApi();
-  const params = useParams();
-  const location = useLocation();
-  const routes = useRoutes();
-
-  const [data, setData] = useState<State>(getInitialState());
-  const [isSaving, setIsSaving] = useState(false);
-
-  const conditionCategories = generateConditionCategoriesOptions(
-    type === SamplingRuleType.TRACE
-      ? distributedTracesConditions
-      : individualTransactionsConditions
-  );
-
-  useEffect(() => {
-    setData(d => {
-      if (!!d.errors.sampleRate) {
-        return {...d, errors: {...d.errors, sampleRate: undefined}};
-      }
-
-      return d;
-    });
-  }, [data.sampleRate]);
-
-  function getInitialState(): State {
-    if (rule) {
-      const {condition: conditions, sampleRate} = rule;
-
-      const {inner} = conditions;
-
-      return {
-        conditions: inner.map(innerItem => {
-          const {name, value} = innerItem;
-
-          if (Array.isArray(value)) {
-            if (isLegacyBrowser(value)) {
-              return {
-                category: name,
-                legacyBrowsers: value,
-              };
-            }
-            return {
-              category: name,
-              match: value.join('\n'),
-            };
-          }
-          return {category: name};
-        }),
-        sampleRate: sampleRate * 100,
-        errors: {},
-      };
-    }
-
-    return {
-      conditions: [],
-      sampleRate: null,
-      errors: {},
-    };
-  }
-
-  function getDescription() {
-    if (type === SamplingRuleType.TRACE) {
-      return {
-        title: rule ? t('Edit Distributed Trace Rule') : t('Add Distributed Trace Rule'),
-        description: tct(
-          'Using a Trace ID, select all Transactions distributed across multiple projects/services which match your conditions. However, if you only want to select Transactions from within this project, we recommend you add a [link] rule instead.',
-          {
-            link: (
-              <Link
-                to={recreateRoute(`${SamplingRuleType.TRANSACTION}/`, {
-                  routes,
-                  location,
-                  params,
-                  stepBack: -1,
-                })}
-              >
-                {t('Individual Transaction')}
-              </Link>
-            ),
-          }
-        ),
-      };
-    }
-
-    return {
-      title: rule
-        ? t('Edit Individual Transaction Rule')
-        : t('Add Individual Transaction Rule'),
-      description: tct(
-        'Select Transactions only within this project which match your conditions. However, If you want to select all Transactions distributed across multiple projects/services, we recommend you add a [link] rule instead.',
-        {
-          link: (
-            <Link
-              to={recreateRoute(`${SamplingRuleType.TRACE}/`, {
-                routes,
-                location,
-                params,
-                stepBack: -1,
-              })}
-            >
-              {t('Distributed Trace')}
-            </Link>
-          ),
-        }
-      ),
-    };
-  }
-
-  const {errors, conditions, sampleRate} = data;
-
-  function convertRequestErrorResponse(error: ReturnType<typeof getErrorMessage>) {
-    if (typeof error === 'string') {
-      addErrorMessage(error);
-      return;
-    }
-
-    switch (error.type) {
-      case 'sampleRate':
-        setData({...data, errors: {...errors, sampleRate: error.message}});
-        break;
-      default:
-        addErrorMessage(error.message);
-    }
-  }
-
-  async function handleSubmit() {
-    if (!defined(sampleRate)) {
-      return;
-    }
-
-    const newRule: SamplingRule = {
-      // All new/updated rules must have id equal to 0
-      id: 0,
-      type,
-      condition: {
-        op: SamplingConditionOperator.AND,
-        inner: !conditions.length ? [] : conditions.map(getNewCondition),
-      },
-      sampleRate: sampleRate / 100,
-    };
-
-    const newTransactionRules = rule
-      ? rules.map(r => (isEqual(r, rule) ? newRule : r))
-      : [...rules, newRule];
-
-    const [transactionTraceRules, individualTransactionRules] = partition(
-      newTransactionRules,
-      transactionRule => transactionRule.type === SamplingRuleType.TRACE
-    );
-
-    const newRules = [...transactionTraceRules, ...individualTransactionRules];
-
-    const currentRuleIndex = newRules.findIndex(newR => newR === newRule);
-
-    setIsSaving(true);
-
-    try {
-      const newProjectDetails = await api.requestPromise(
-        `/projects/${organization.slug}/${project.slug}/`,
-        {method: 'PUT', data: {dynamicSampling: {rules: newRules}}}
-      );
-      onSubmitSuccess(
-        newProjectDetails,
-        rule
-          ? t('Successfully edited sampling rule')
-          : t('Successfully added sampling rule')
-      );
-      closeModal();
-    } catch (error) {
-      convertRequestErrorResponse(getErrorMessage(error, currentRuleIndex));
-    }
-
-    setIsSaving(false);
-
-    const analyticsConditions = conditions.map(condition => condition.category);
-    const analyticsConditionsStringified = analyticsConditions.sort().join(', ');
-
-    trackAdvancedAnalyticsEvent('sampling.settings.rule.save', {
-      organization,
-      project_id: project.id,
-      sampling_rate: sampleRate,
-      conditions: analyticsConditions,
-      conditions_stringified: analyticsConditionsStringified,
-    });
-
-    if (defined(rule)) {
-      trackAdvancedAnalyticsEvent('sampling.settings.rule.update', {
-        organization,
-        project_id: project.id,
-        sampling_rate: sampleRate,
-        conditions: analyticsConditions,
-        conditions_stringified: analyticsConditionsStringified,
-        old_conditions: rule.condition.inner.map(({name}) => name),
-        old_conditions_stringified: rule.condition.inner
-          .map(({name}) => name)
-          .sort()
-          .join(', '),
-        old_sampling_rate: rule.sampleRate * 100,
-      });
-      return;
-    }
-
-    trackAdvancedAnalyticsEvent('sampling.settings.rule.create', {
-      organization,
-      project_id: project.id,
-      sampling_rate: sampleRate,
-      conditions: analyticsConditions,
-      conditions_stringified: analyticsConditionsStringified,
-    });
-  }
-
-  function handleAddCondition(selectedOptions: SelectValue<SamplingInnerName>[]) {
-    const previousCategories = conditions.map(({category}) => category);
-    const addedCategories = selectedOptions
-      .filter(
-        ({value}) =>
-          value === SamplingInnerName.EVENT_CUSTOM_TAG || // We can have more than 1 custom tag rules
-          !previousCategories.includes(value)
-      )
-      .map(({value}) => value);
-
-    trackAdvancedAnalyticsEvent('sampling.settings.condition.add', {
-      organization,
-      project_id: project.id,
-      conditions: addedCategories,
-    });
-
-    setData({
-      ...data,
-      conditions: [
-        ...conditions,
-        ...addedCategories.map(addedCategory => ({category: addedCategory, match: ''})),
-      ],
-    });
-  }
-
-  function handleDeleteCondition(index: number) {
-    const newConditions = [...conditions];
-    newConditions.splice(index, 1);
-    setData({...data, conditions: newConditions});
-  }
-
-  function handleChangeCondition<T extends keyof ConditionsProps[0]>(
-    index: number,
-    field: T,
-    value: ConditionsProps[0][T]
-  ) {
-    const newConditions = [...conditions];
-    newConditions[index][field] = value;
-
-    // If custom tag key changes, reset the value
-    if (field === 'category') {
-      newConditions[index].match = '';
-
-      trackAdvancedAnalyticsEvent('sampling.settings.condition.add', {
-        organization,
-        project_id: project.id,
-        conditions: [value as SamplingInnerName],
-      });
-    }
-
-    setData({...data, conditions: newConditions});
-  }
-
-  // Distributed Trace and Individual Transaction Rule can only have one 'sample all' rule at a time
-  const ruleWithoutConditionExists = rules
-    .filter(r => r.type === type && !isEqual(r, rule))
-    .some(r => !r.condition.inner.length);
-
-  const submitDisabled =
-    !defined(sampleRate) ||
-    (ruleWithoutConditionExists && !conditions.length) ||
-    !!conditions?.find(condition => {
-      if (condition.category === SamplingInnerName.EVENT_LEGACY_BROWSER) {
-        return !(condition.legacyBrowsers ?? []).length;
-      }
-
-      if (
-        condition.category === SamplingInnerName.EVENT_LOCALHOST ||
-        condition.category === SamplingInnerName.EVENT_WEB_CRAWLERS
-      ) {
-        return false;
-      }
-
-      // They probably did not specify custom tag key
-      if (
-        condition.category === '' ||
-        condition.category === SamplingInnerName.EVENT_CUSTOM_TAG
-      ) {
-        return true;
-      }
-
-      return !condition.match;
-    });
-
-  const customTagConditionsOptions = conditions
-    .filter(
-      condition =>
-        isCustomTagName(condition.category) &&
-        condition.category !== SamplingInnerName.EVENT_CUSTOM_TAG
-    )
-    .map(({category}) => ({
-      value: category,
-      label: (
-        <Truncate value={getInnerNameLabel(category)} expandable={false} maxLength={40} />
-      ),
-      disabled: true,
-      tooltip: conditionAlreadyAddedTooltip,
-    }));
-
-  const predefinedConditionsOptions = conditionCategories.map(([value, label]) => {
-    // Never disable the "Add Custom Tag" option, you can add more of those
-    const optionDisabled =
-      value === SamplingInnerName.EVENT_CUSTOM_TAG
-        ? false
-        : conditions.some(condition => condition.category === value);
-    return {
-      value,
-      label,
-      disabled: optionDisabled,
-      tooltip: disabled ? conditionAlreadyAddedTooltip : undefined,
-    };
-  });
-
-  const {title, description} = getDescription();
-
-  return (
-    <Fragment>
-      <Header closeButton>
-        <h4>{title}</h4>
-      </Header>
-      <Body>
-        <Fields>
-          <Description>{description}</Description>
-          <StyledPanel>
-            <StyledPanelHeader hasButtons>
-              {t('Conditions')}
-              <StyledCompactSelect
-                placement="bottom right"
-                triggerProps={{
-                  size: 'sm',
-                  'aria-label': t('Add Condition'),
-                }}
-                triggerLabel={
-                  <TriggerLabel>
-                    <IconAdd isCircled />
-                    {t('Add Condition')}
-                  </TriggerLabel>
-                }
-                placeholder={t('Filter conditions')}
-                isOptionDisabled={opt => opt.disabled}
-                options={[...customTagConditionsOptions, ...predefinedConditionsOptions]}
-                value={conditions
-                  // We need to filter our custom tag option so that it can be selected multiple times without being unselected every other time
-                  .filter(({category}) => category !== SamplingInnerName.EVENT_CUSTOM_TAG)
-                  .map(({category}) => category)}
-                onChange={handleAddCondition}
-                isSearchable
-                multiple
-                filterOption={(candidate, input) => {
-                  // Always offer the "Add Custom Tag" option in the autocomplete
-                  if (candidate.value === SamplingInnerName.EVENT_CUSTOM_TAG) {
-                    return true;
-                  }
-                  return createFilter(null)(candidate, input);
-                }}
-                components={{
-                  Option: containerProps => {
-                    if (containerProps.value === SamplingInnerName.EVENT_CUSTOM_TAG) {
-                      return (
-                        <components.Option className="select-option" {...containerProps}>
-                          <AddCustomTag isFocused={containerProps.isFocused}>
-                            <IconAdd isCircled /> {t('Add Custom Tag')}
-                          </AddCustomTag>
-                        </components.Option>
-                      );
-                    }
-                    return <Option {...containerProps} />;
-                  },
-                }}
-              />
-            </StyledPanelHeader>
-            <PanelBody>
-              {ruleWithoutConditionExists && (
-                <PanelAlert type="info">
-                  {t(
-                    'A rule with no conditions already exists. You can edit that existing rule or add a condition to this rule'
-                  )}
-                </PanelAlert>
-              )}
-              {!conditions.length ? (
-                <EmptyMessage
-                  icon={<IconSearch size="xl" />}
-                  title={t('No conditions added')}
-                  description={tct(
-                    "if you don't want to add (+) a condition, [lineBreak]simply, add a sample rate below",
-                    {
-                      lineBreak: <br />,
-                    }
-                  )}
-                />
-              ) : (
-                <Conditions
-                  conditions={conditions}
-                  onDelete={handleDeleteCondition}
-                  onChange={handleChangeCondition}
-                  orgSlug={organization.slug}
-                  projectId={project.id}
-                  projectSlug={project.slug}
-                />
-              )}
-            </PanelBody>
-          </StyledPanel>
-          <NumberField
-            label={`${t('Sample Rate')} \u0025`}
-            name="sampleRate"
-            onChange={value => {
-              setData({...data, sampleRate: !!value ? Number(value) : null});
-            }}
-            onKeyDown={(_value: string, e: KeyboardEvent) => {
-              if (e.key === 'Enter') {
-                handleSubmit();
-              }
-            }}
-            placeholder={'\u0025'}
-            value={sampleRate}
-            inline={false}
-            hideControlState={!errors.sampleRate}
-            error={errors.sampleRate}
-            showHelpInTooltip
-            stacked
-            required
-          />
-        </Fields>
-      </Body>
-      <Footer>
-        <ButtonBar gap={1}>
-          <Button onClick={closeModal}>{t('Cancel')}</Button>
-          <Button
-            priority="primary"
-            onClick={handleSubmit}
-            title={
-              disabled
-                ? t('You do not have permission to add sampling rules.')
-                : submitDisabled
-                ? t('Required fields must be filled out')
-                : undefined
-            }
-            disabled={disabled || isSaving || submitDisabled}
-          >
-            {t('Save Rule')}
-          </Button>
-        </ButtonBar>
-      </Footer>
-    </Fragment>
-  );
-}
-
-const Fields = styled('div')`
-  display: grid;
-  gap: ${space(2)};
-`;
-
-const StyledCompactSelect = styled(CompactSelect)`
-  font-weight: 400;
-  text-transform: none;
-`;
-
-const StyledPanelHeader = styled(PanelHeader)`
-  padding-right: ${space(2)};
-`;
-
-const StyledPanel = styled(Panel)`
-  margin-bottom: 0;
-`;
-
-const AddCustomTag = styled('div')<{isFocused: boolean}>`
-  display: flex;
-  align-items: center;
-  padding: ${space(1)} ${space(1)} ${space(1)} ${space(1.5)};
-  gap: ${space(1)};
-  line-height: 1.4;
-  border-radius: ${p => p.theme.borderRadius};
-  ${p => p.isFocused && `background: ${p.theme.hover};`};
-`;
-
-const TriggerLabel = styled('div')`
-  display: grid;
-  grid-template-columns: repeat(2, max-content);
-  align-items: center;
-  gap: ${space(1)};
-`;
-
-const Description = styled(TextBlock)`
-  margin: 0;
-`;

+ 0 - 94
static/app/views/settings/project/sampling/modal/legacyBrowsers.tsx

@@ -1,94 +0,0 @@
-import {Fragment} from 'react';
-import styled from '@emotion/styled';
-
-import BulkController from 'sentry/components/bulkController';
-import Switch from 'sentry/components/switchButton';
-import {t} from 'sentry/locale';
-import space from 'sentry/styles/space';
-import {LegacyBrowser} from 'sentry/types/sampling';
-
-import {LEGACY_BROWSER_LIST} from '../utils';
-
-const legacyBrowsers = Object.values(LegacyBrowser) as Array<LegacyBrowser>;
-
-type Props = {
-  onChange: (selectedLegacyBrowsers: Array<LegacyBrowser>) => void;
-  selectedLegacyBrowsers?: Array<LegacyBrowser>;
-};
-
-function LegacyBrowsers({onChange, selectedLegacyBrowsers = []}: Props) {
-  function handleChange({
-    selectedIds,
-  }: Parameters<NonNullable<BulkController['props']['onChange']>>[0]) {
-    onChange(selectedIds as Array<LegacyBrowser>);
-  }
-
-  return (
-    <BulkController
-      pageIds={legacyBrowsers}
-      defaultSelectedIds={selectedLegacyBrowsers}
-      allRowsCount={legacyBrowsers.length}
-      onChange={handleChange}
-      columnsCount={0}
-    >
-      {({selectedIds, onRowToggle, onPageRowsToggle, isPageSelected}) => (
-        <Wrapper>
-          {t('All browsers')}
-          <Switch
-            key="switch"
-            size="lg"
-            isActive={isPageSelected}
-            toggle={() => {
-              onPageRowsToggle(!isPageSelected);
-            }}
-          />
-          {legacyBrowsers.map(legacyBrowser => {
-            const {icon, title} = LEGACY_BROWSER_LIST[legacyBrowser];
-            return (
-              <Fragment key={legacyBrowser}>
-                <BrowserWrapper>
-                  <Icon className={`icon-${icon}`} data-test-id={`icon-${icon}`} />
-                  {title}
-                </BrowserWrapper>
-                <Switch
-                  size="lg"
-                  isActive={selectedIds.includes(legacyBrowser)}
-                  toggle={() => onRowToggle(legacyBrowser)}
-                />
-              </Fragment>
-            );
-          })}
-        </Wrapper>
-      )}
-    </BulkController>
-  );
-}
-
-export default LegacyBrowsers;
-
-const Wrapper = styled('div')`
-  grid-column: 1/-1;
-  display: grid;
-  grid-template-columns: 1fr max-content;
-  gap: ${space(2)};
-  font-size: ${p => p.theme.fontSizeLarge};
-  color: ${p => p.theme.gray400};
-  padding-top: ${space(2)};
-  padding-bottom: ${space(1)};
-`;
-
-const BrowserWrapper = styled('div')`
-  display: grid;
-  grid-template-columns: max-content 1fr;
-  grid-column-gap: ${space(1)};
-  color: ${p => p.theme.gray500};
-`;
-
-const Icon = styled('div')`
-  width: 24px;
-  height: 24px;
-  background-repeat: no-repeat;
-  background-position: center;
-  background-size: 24px 24px;
-  flex-shrink: 0;
-`;

+ 0 - 71
static/app/views/settings/project/sampling/modal/tagKeyAutocomplete.tsx

@@ -1,71 +0,0 @@
-import styled from '@emotion/styled';
-
-import SelectField from 'sentry/components/forms/selectField';
-import {t} from 'sentry/locale';
-import {Tag} from 'sentry/types';
-import {SamplingInnerName} from 'sentry/types/sampling';
-
-import {TruncatedLabel} from './truncatedLabel';
-import {formatCreateTagLabel} from './utils';
-
-type Props = {
-  disabledOptions: string[];
-  onChange: (value: string) => void;
-  tags: Tag[];
-  value?: string;
-};
-
-/**
- * This component is used for the autocomplete of custom tag key
- */
-function TagKeyAutocomplete({tags, onChange, value, disabledOptions}: Props) {
-  // select doesn't play nicely with selected values that are not in the listed options
-  const options = tags.map(({key}) => ({
-    value: key,
-    label: <TruncatedLabel value={key} />,
-  }));
-
-  if (
-    value &&
-    value !== SamplingInnerName.EVENT_CUSTOM_TAG &&
-    !tags.some(({key}) => key === value)
-  ) {
-    options.push({
-      value,
-      label: <TruncatedLabel value={value} />,
-    });
-  }
-
-  return (
-    <Wrapper>
-      <SelectField
-        aria-label={t('Search or add a tag')}
-        name="customTagKey"
-        options={options}
-        isOptionDisabled={option => disabledOptions.includes(option.value)}
-        inline={false}
-        stacked
-        hideControlState
-        required
-        creatable
-        placeholder={t('tag')}
-        onChange={onChange}
-        value={value}
-        formatCreateLabel={formatCreateTagLabel}
-        isValidNewOption={newOption => {
-          // Tag keys cannot be empty and must have a maximum length of 32 characters
-          // https://github.com/getsentry/relay/blob/d8223d8d03ed4764063855eb3480f22684163d92/relay-general/src/store/normalize.rs#L220-L240
-          // In addition to that, it must be composed of numbers and/or letters and the only special characters allowed are "-", "_", "." and ":"
-          // https://github.com/getsentry/relay/blob/d8223d8d03ed4764063855eb3480f22684163d92/relay-general/src/protocol/tags.rs#L7
-          return /^([a-zA-Z0-9_\\:\\.\\-]+)$/.test(newOption) && newOption.length <= 32;
-        }}
-      />
-    </Wrapper>
-  );
-}
-
-const Wrapper = styled('div')`
-  width: 100%;
-`;
-
-export {TagKeyAutocomplete};

+ 0 - 156
static/app/views/settings/project/sampling/modal/tagValueAutocomplete.tsx

@@ -1,156 +0,0 @@
-import {useCallback, useEffect, useState} from 'react';
-import {components, MultiValueProps} from 'react-select';
-import styled from '@emotion/styled';
-
-import {fetchTagValues} from 'sentry/actionCreators/tags';
-import SelectField from 'sentry/components/forms/selectField';
-import {t} from 'sentry/locale';
-import {Organization, Project} from 'sentry/types';
-import {SamplingInnerName} from 'sentry/types/sampling';
-import useApi from 'sentry/utils/useApi';
-
-import {TruncatedLabel} from './truncatedLabel';
-import {formatCreateTagLabel, getMatchFieldPlaceholder} from './utils';
-
-type Tag = {
-  value: string;
-};
-
-type Props = {
-  category:
-    | SamplingInnerName.EVENT_ENVIRONMENT
-    | SamplingInnerName.EVENT_RELEASE
-    | SamplingInnerName.EVENT_TRANSACTION
-    | SamplingInnerName.EVENT_OS_NAME
-    | SamplingInnerName.EVENT_OS_VERSION
-    | SamplingInnerName.EVENT_DEVICE_FAMILY
-    | SamplingInnerName.EVENT_DEVICE_NAME
-    | SamplingInnerName.EVENT_CUSTOM_TAG
-    | SamplingInnerName.TRACE_ENVIRONMENT
-    | SamplingInnerName.TRACE_RELEASE
-    | SamplingInnerName.TRACE_TRANSACTION
-    | string;
-  onChange: (value: string) => void;
-  orgSlug: Organization['slug'];
-  projectId: Project['id'];
-  tagKey?: string;
-  value?: string;
-};
-
-function TagValueAutocomplete({
-  orgSlug,
-  projectId,
-  category,
-  onChange,
-  value,
-  tagKey,
-}: Props) {
-  const api = useApi();
-  const [tagValues, setTagValues] = useState<Tag[]>([]);
-
-  function getAriaLabel() {
-    switch (category) {
-      case SamplingInnerName.TRACE_RELEASE:
-      case SamplingInnerName.EVENT_RELEASE:
-        return t('Search or add a release');
-      case SamplingInnerName.TRACE_ENVIRONMENT:
-      case SamplingInnerName.EVENT_ENVIRONMENT:
-        return t('Search or add an environment');
-      case SamplingInnerName.TRACE_TRANSACTION:
-      case SamplingInnerName.EVENT_TRANSACTION:
-        return t('Search or add a transaction');
-      case SamplingInnerName.EVENT_OS_NAME:
-        return t('Search or add an os name');
-      case SamplingInnerName.EVENT_OS_VERSION:
-        return t('Search or add an os version');
-      case SamplingInnerName.EVENT_DEVICE_FAMILY:
-        return t('Search or add a device family');
-      case SamplingInnerName.EVENT_DEVICE_NAME:
-        return t('Search or add a device name');
-
-      default:
-        // custom tags
-        return t('Search or add tag values');
-    }
-  }
-
-  const tagValueLoader = useCallback(async () => {
-    if (!tagKey) {
-      return;
-    }
-
-    try {
-      const response = await fetchTagValues(
-        api,
-        orgSlug,
-        tagKey,
-        null,
-        [projectId],
-        null,
-        true
-      );
-      setTagValues(response);
-    } catch {
-      // Do nothing. No results will be suggested
-    }
-  }, [tagKey, api, orgSlug, projectId]);
-
-  useEffect(() => {
-    tagValueLoader();
-  }, [tagValueLoader]);
-
-  // react-select doesn't seem to work very well when its value contains
-  // a created item that isn't listed in the options
-  const createdOptions: Tag[] = !value
-    ? []
-    : value
-        .split('\n')
-        .filter(v => !tagValues.some(tagValue => tagValue.value === v))
-        .map(v => ({value: v}));
-
-  return (
-    <StyledSelectField
-      name="match"
-      aria-label={getAriaLabel()}
-      options={[...createdOptions, ...tagValues].map(tagValue => ({
-        value: tagValue.value,
-        label: <TruncatedLabel value={tagValue.value} />,
-      }))}
-      value={value?.split('\n')}
-      onChange={newValue => {
-        onChange(newValue?.join('\n'));
-      }}
-      components={{
-        MultiValue: (multiValueProps: MultiValueProps<{}>) => (
-          <components.MultiValue
-            {...multiValueProps}
-            innerProps={{...multiValueProps.innerProps, 'data-test-id': 'multivalue'}}
-          />
-        ),
-      }}
-      formatCreateLabel={formatCreateTagLabel}
-      isValidNewOption={newOption => {
-        // Tag values cannot be empty and must have a maximum length of 200 characters
-        // https://github.com/getsentry/relay/blob/d8223d8d03ed4764063855eb3480f22684163d92/relay-general/src/store/normalize.rs#L230-L236
-        // In addition to that, it cannot contain a line-feed (newline) character
-        // https://github.com/getsentry/relay/blob/d8223d8d03ed4764063855eb3480f22684163d92/relay-general/src/protocol/tags.rs#L8
-        return !/\\n/.test(newOption) && newOption.length <= 200;
-      }}
-      placeholder={getMatchFieldPlaceholder(category)}
-      inline={false}
-      multiple
-      hideControlState
-      flexibleControlStateSize
-      required
-      stacked
-      creatable
-      allowClear
-    />
-  );
-}
-
-const StyledSelectField = styled(SelectField)`
-  width: 100%;
-`;
-
-export {TagValueAutocomplete};

+ 0 - 15
static/app/views/settings/project/sampling/modal/truncatedLabel.tsx

@@ -1,15 +0,0 @@
-import Truncate from 'sentry/components/truncate';
-import theme from 'sentry/utils/theme';
-import useMedia from 'sentry/utils/useMedia';
-
-type Props = {
-  value: string;
-};
-
-export function TruncatedLabel({value}: Props) {
-  const isSmallDevice = useMedia(`(max-width: ${theme.breakpoints.small})`);
-
-  return (
-    <Truncate value={value} maxLength={isSmallDevice ? 30 : 40} expandable={false} />
-  );
-}

+ 0 - 304
static/app/views/settings/project/sampling/modal/utils.tsx

@@ -1,304 +0,0 @@
-import {css} from '@emotion/react';
-
-import {t, tct} from 'sentry/locale';
-import {
-  LegacyBrowser,
-  SamplingConditionLogicalInner,
-  SamplingInnerName,
-  SamplingInnerOperator,
-  SamplingRule,
-} from 'sentry/types/sampling';
-import theme from 'sentry/utils/theme';
-
-import {
-  getInnerNameLabel,
-  isCustomTagName,
-  LEGACY_BROWSER_LIST,
-  stripCustomTagPrefix,
-} from '../utils';
-
-import Conditions from './conditions';
-import {TruncatedLabel} from './truncatedLabel';
-
-type Condition = React.ComponentProps<typeof Conditions>['conditions'][0];
-
-export const modalCss = css`
-  [role='document'] {
-    overflow: initial;
-  }
-
-  @media (min-width: ${theme.breakpoints.small}) {
-    width: 100%;
-    max-width: 700px;
-  }
-`;
-
-export enum Transaction {
-  ALL = 'all',
-  MATCH_CONDITIONS = 'match-conditions',
-}
-
-export function isLegacyBrowser(
-  maybe: Array<string> | Array<LegacyBrowser>
-): maybe is Array<LegacyBrowser> {
-  return maybe.every(m => !!LEGACY_BROWSER_LIST[m]);
-}
-
-export function getMatchFieldPlaceholder(category: SamplingInnerName | string) {
-  switch (category) {
-    case SamplingInnerName.EVENT_LEGACY_BROWSER:
-      return t('Match all selected legacy browsers below');
-    case SamplingInnerName.EVENT_LOCALHOST:
-      return t('Match all localhosts');
-    case SamplingInnerName.EVENT_WEB_CRAWLERS:
-      return t('Match all web crawlers');
-    case SamplingInnerName.EVENT_USER_ID:
-    case SamplingInnerName.TRACE_USER_ID:
-      return t('ex. 4711 (Multiline)');
-    case SamplingInnerName.EVENT_USER_SEGMENT:
-    case SamplingInnerName.TRACE_USER_SEGMENT:
-      return t('ex. paid, common (Multiline)');
-    case SamplingInnerName.TRACE_ENVIRONMENT:
-    case SamplingInnerName.EVENT_ENVIRONMENT:
-      return t('ex. prod, dev');
-    case SamplingInnerName.TRACE_RELEASE:
-    case SamplingInnerName.EVENT_RELEASE:
-      return t('ex. 1*, [I3].[0-9].*');
-    case SamplingInnerName.EVENT_IP_ADDRESSES:
-      return t('ex. 127.0.0.1 or 10.0.0.0/8 (Multiline)');
-    case SamplingInnerName.EVENT_CSP:
-      return t('ex. file://*, example.com (Multiline)');
-    case SamplingInnerName.TRACE_TRANSACTION:
-    case SamplingInnerName.EVENT_TRANSACTION:
-      return t('ex. page-load');
-    case SamplingInnerName.EVENT_OS_NAME:
-      return t('ex. Mac OS X, Windows');
-    case SamplingInnerName.EVENT_OS_VERSION:
-      return t('ex. 11, 9* (Multiline)');
-    case SamplingInnerName.EVENT_DEVICE_FAMILY:
-      return t('ex. Mac, Pixel*');
-    case SamplingInnerName.EVENT_DEVICE_NAME:
-      return t('ex. Mac, Pixel*');
-    default:
-      return t('tag values');
-  }
-}
-
-export function getNewCondition(condition: Condition): SamplingConditionLogicalInner {
-  // SamplingConditionLogicalInnerEqBoolean
-  if (
-    condition.category === SamplingInnerName.EVENT_WEB_CRAWLERS ||
-    condition.category === SamplingInnerName.EVENT_LOCALHOST
-  ) {
-    return {
-      op: SamplingInnerOperator.EQUAL,
-      name: condition.category,
-      value: true,
-    };
-  }
-
-  // SamplingConditionLogicalInnerCustom
-  if (condition.category === SamplingInnerName.EVENT_LEGACY_BROWSER) {
-    return {
-      op: SamplingInnerOperator.CUSTOM,
-      name: condition.category,
-      value: condition.legacyBrowsers ?? [],
-    };
-  }
-
-  const newValue = (condition.match ?? '')
-    .split('\n')
-    .filter(match => !!match.trim())
-    .map(match => match.trim());
-
-  if (
-    condition.category === SamplingInnerName.EVENT_IP_ADDRESSES ||
-    condition.category === SamplingInnerName.EVENT_CSP
-  ) {
-    return {
-      op: SamplingInnerOperator.CUSTOM,
-      name: condition.category,
-      value: newValue,
-    };
-  }
-
-  // SamplingConditionLogicalInnerGlob
-  if (
-    condition.category === SamplingInnerName.EVENT_RELEASE ||
-    condition.category === SamplingInnerName.TRACE_RELEASE ||
-    condition.category === SamplingInnerName.EVENT_TRANSACTION ||
-    condition.category === SamplingInnerName.TRACE_TRANSACTION ||
-    condition.category === SamplingInnerName.EVENT_OS_NAME ||
-    condition.category === SamplingInnerName.EVENT_OS_VERSION ||
-    condition.category === SamplingInnerName.EVENT_DEVICE_FAMILY ||
-    condition.category === SamplingInnerName.EVENT_DEVICE_NAME ||
-    isCustomTagName(condition.category)
-  ) {
-    return {
-      op: SamplingInnerOperator.GLOB_MATCH,
-      name: condition.category,
-      value: newValue,
-    };
-  }
-
-  // SamplingConditionLogicalInnerEq
-  if (
-    condition.category === SamplingInnerName.TRACE_USER_ID ||
-    condition.category === SamplingInnerName.EVENT_USER_ID
-  ) {
-    return {
-      op: SamplingInnerOperator.EQUAL,
-      name: condition.category,
-      value: newValue,
-      options: {
-        ignoreCase: false,
-      },
-    };
-  }
-
-  // SamplingConditionLogicalInnerEq
-  return {
-    op: SamplingInnerOperator.EQUAL,
-    // TODO(sampling): remove the cast
-    name: condition.category as
-      | SamplingInnerName.TRACE_ENVIRONMENT
-      | SamplingInnerName.TRACE_USER_ID
-      | SamplingInnerName.TRACE_USER_SEGMENT
-      | SamplingInnerName.EVENT_ENVIRONMENT
-      | SamplingInnerName.EVENT_USER_ID
-      | SamplingInnerName.EVENT_USER_SEGMENT,
-    value: newValue,
-    options: {
-      ignoreCase: true,
-    },
-  };
-}
-
-const unexpectedErrorMessage = t('An internal error occurred while saving sampling rule');
-
-type ResponseJSONDetailed = {
-  detail: string[];
-};
-
-type ResponseJSON = {
-  dynamicSampling?: {
-    rules: Array<Partial<SamplingRule>>;
-  };
-};
-
-export function getErrorMessage(
-  error: {
-    responseJSON?: ResponseJSON | ResponseJSONDetailed;
-  },
-  currentRuleIndex: number
-) {
-  const detailedErrorResponse = (error.responseJSON as undefined | ResponseJSONDetailed)
-    ?.detail;
-
-  if (detailedErrorResponse) {
-    // This is a temp solution until we enable error rules again, therefore it does not need translation
-    return detailedErrorResponse[0];
-  }
-
-  const errorResponse = error.responseJSON as undefined | ResponseJSON;
-
-  if (!errorResponse) {
-    return unexpectedErrorMessage;
-  }
-
-  const responseErrors = errorResponse.dynamicSampling?.rules[currentRuleIndex] ?? {};
-
-  const [type, _value] = Object.entries(responseErrors)[0];
-
-  if (type === 'sampleRate') {
-    return {
-      type: 'sampleRate',
-      message: t('Ensure this value is a floating number between 0 and 100'),
-    };
-  }
-
-  return unexpectedErrorMessage;
-}
-
-export function getTagKey(condition: Condition) {
-  switch (condition.category) {
-    case SamplingInnerName.TRACE_RELEASE:
-    case SamplingInnerName.EVENT_RELEASE:
-      return 'release';
-    case SamplingInnerName.TRACE_ENVIRONMENT:
-    case SamplingInnerName.EVENT_ENVIRONMENT:
-      return 'environment';
-    case SamplingInnerName.TRACE_TRANSACTION:
-    case SamplingInnerName.EVENT_TRANSACTION:
-      return 'transaction';
-    case SamplingInnerName.EVENT_OS_NAME:
-      return 'os.name';
-    case SamplingInnerName.EVENT_OS_VERSION:
-      return 'os.version';
-    case SamplingInnerName.EVENT_DEVICE_FAMILY:
-      return 'device.family';
-    case SamplingInnerName.EVENT_DEVICE_NAME:
-      return 'device.name';
-    case SamplingInnerName.EVENT_CUSTOM_TAG:
-      return '';
-    default:
-      // custom tags
-      return stripCustomTagPrefix(condition.category);
-  }
-}
-
-export const distributedTracesConditions = [
-  SamplingInnerName.TRACE_RELEASE,
-  SamplingInnerName.TRACE_ENVIRONMENT,
-  SamplingInnerName.TRACE_USER_ID,
-  SamplingInnerName.TRACE_USER_SEGMENT,
-  SamplingInnerName.TRACE_TRANSACTION,
-];
-
-export const individualTransactionsConditions = [
-  SamplingInnerName.EVENT_RELEASE,
-  SamplingInnerName.EVENT_ENVIRONMENT,
-  SamplingInnerName.EVENT_USER_ID,
-  SamplingInnerName.EVENT_USER_SEGMENT,
-  SamplingInnerName.EVENT_LOCALHOST,
-  SamplingInnerName.EVENT_LEGACY_BROWSER,
-  SamplingInnerName.EVENT_WEB_CRAWLERS,
-  SamplingInnerName.EVENT_IP_ADDRESSES,
-  SamplingInnerName.EVENT_CSP,
-  SamplingInnerName.EVENT_TRANSACTION,
-  SamplingInnerName.EVENT_OS_NAME,
-  SamplingInnerName.EVENT_OS_VERSION,
-  SamplingInnerName.EVENT_DEVICE_FAMILY,
-  SamplingInnerName.EVENT_DEVICE_NAME,
-  SamplingInnerName.EVENT_CUSTOM_TAG,
-];
-
-export function generateConditionCategoriesOptions(
-  conditionCategories: SamplingInnerName[]
-): [SamplingInnerName, string][] {
-  const hasCustomTagCategory = conditionCategories.includes(
-    SamplingInnerName.EVENT_CUSTOM_TAG
-  );
-
-  const sortedConditionCategories = conditionCategories
-    // filter our custom tag category, we will append it to the bottom
-    .filter(category => category !== SamplingInnerName.EVENT_CUSTOM_TAG)
-    // sort dropdown options alphabetically based on display labels
-    .sort((a, b) => getInnerNameLabel(a).localeCompare(getInnerNameLabel(b)));
-
-  if (hasCustomTagCategory) {
-    sortedConditionCategories.push(SamplingInnerName.EVENT_CUSTOM_TAG);
-  }
-
-  // massage into format that select component understands
-  return sortedConditionCategories.map(innerName => [
-    innerName,
-    getInnerNameLabel(innerName),
-  ]);
-}
-
-export function formatCreateTagLabel(label: string) {
-  return tct('Add "[newLabel]"', {
-    newLabel: <TruncatedLabel value={label} />,
-  });
-}

Some files were not shown because too many files changed in this diff