(
*
* [1]: https://develop.sentry.dev/frontend/network-requests/
*/
-class DeprecatedAsyncComponent<
+export class DeprecatedAsyncComponent<
P extends AsyncComponentProps = AsyncComponentProps,
S extends AsyncComponentState = AsyncComponentState,
> extends Component {
@@ -389,5 +389,3 @@ class DeprecatedAsyncComponent<
return this.renderComponent();
}
}
-
-export default DeprecatedAsyncComponent;
diff --git a/static/app/components/deprecatedforms/booleanField.spec.tsx b/static/app/components/deprecatedforms/booleanField.spec.tsx
index 05478d7edef641..92f02921120071 100644
--- a/static/app/components/deprecatedforms/booleanField.spec.tsx
+++ b/static/app/components/deprecatedforms/booleanField.spec.tsx
@@ -1,7 +1,7 @@
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import BooleanField from 'sentry/components/deprecatedforms/booleanField';
-import Form from 'sentry/components/deprecatedforms/form';
+import {Form} from 'sentry/components/deprecatedforms/form';
describe('BooleanField', () => {
it('renders without form context', () => {
diff --git a/static/app/components/deprecatedforms/booleanField.tsx b/static/app/components/deprecatedforms/booleanField.tsx
index e9faf207257e13..05bda70075b576 100644
--- a/static/app/components/deprecatedforms/booleanField.tsx
+++ b/static/app/components/deprecatedforms/booleanField.tsx
@@ -1,7 +1,7 @@
import {Checkbox} from '@sentry/scraps/checkbox';
import {Tooltip} from '@sentry/scraps/tooltip';
-import InputField from 'sentry/components/deprecatedforms/inputField';
+import {InputField} from 'sentry/components/deprecatedforms/inputField';
import {withFormContext} from 'sentry/components/deprecatedforms/withFormContext';
import {IconQuestion} from 'sentry/icons';
import {defined} from 'sentry/utils';
diff --git a/static/app/components/deprecatedforms/dateTimeField.tsx b/static/app/components/deprecatedforms/dateTimeField.tsx
index 7745c3956fb82a..0a5357c5cff011 100644
--- a/static/app/components/deprecatedforms/dateTimeField.tsx
+++ b/static/app/components/deprecatedforms/dateTimeField.tsx
@@ -1,4 +1,4 @@
-import InputField from 'sentry/components/deprecatedforms/inputField';
+import {InputField} from 'sentry/components/deprecatedforms/inputField';
/**
* @deprecated Do not use this
diff --git a/static/app/components/deprecatedforms/emailField.spec.tsx b/static/app/components/deprecatedforms/emailField.spec.tsx
index ba74cda991fa52..3144fd69a9ad1a 100644
--- a/static/app/components/deprecatedforms/emailField.spec.tsx
+++ b/static/app/components/deprecatedforms/emailField.spec.tsx
@@ -1,7 +1,7 @@
import {render} from 'sentry-test/reactTestingLibrary';
import EmailField from 'sentry/components/deprecatedforms/emailField';
-import Form from 'sentry/components/deprecatedforms/form';
+import {Form} from 'sentry/components/deprecatedforms/form';
describe('EmailField', () => {
describe('render()', () => {
diff --git a/static/app/components/deprecatedforms/emailField.tsx b/static/app/components/deprecatedforms/emailField.tsx
index 9f76766c16dc1f..6b9b0561298ddf 100644
--- a/static/app/components/deprecatedforms/emailField.tsx
+++ b/static/app/components/deprecatedforms/emailField.tsx
@@ -1,4 +1,4 @@
-import InputField from 'sentry/components/deprecatedforms/inputField';
+import {InputField} from 'sentry/components/deprecatedforms/inputField';
import {withFormContext} from 'sentry/components/deprecatedforms/withFormContext';
// XXX: This is ONLY used in GenericField. If we can delete that this can go.
diff --git a/static/app/components/deprecatedforms/form.spec.tsx b/static/app/components/deprecatedforms/form.spec.tsx
index 5f52d29f1639f2..be58ca853c7921 100644
--- a/static/app/components/deprecatedforms/form.spec.tsx
+++ b/static/app/components/deprecatedforms/form.spec.tsx
@@ -1,6 +1,6 @@
import {render} from 'sentry-test/reactTestingLibrary';
-import Form from 'sentry/components/deprecatedforms/form';
+import {Form} from 'sentry/components/deprecatedforms/form';
describe('Form', () => {
describe('render()', () => {
diff --git a/static/app/components/deprecatedforms/form.tsx b/static/app/components/deprecatedforms/form.tsx
index 1bbbbe4603d895..81b02610bad6ed 100644
--- a/static/app/components/deprecatedforms/form.tsx
+++ b/static/app/components/deprecatedforms/form.tsx
@@ -6,7 +6,7 @@ import {Alert} from '@sentry/scraps/alert';
import {Button} from '@sentry/scraps/button';
import {FormContext} from 'sentry/components/deprecatedforms/formContext';
-import FormState from 'sentry/components/forms/state';
+import {FormState} from 'sentry/components/forms/state';
import {t} from 'sentry/locale';
type FormProps = {
@@ -42,7 +42,7 @@ type FormClassState = {
state: FormState;
};
-class Form<
+export class Form<
Props extends FormProps = FormProps,
State extends FormClassState = FormClassState,
> extends Component {
@@ -191,5 +191,3 @@ class Form<
// Note: this is so we can use this as a selector for SelectField
// We need to keep `Form` as a React Component because ApiForm extends it :/
export const StyledForm = styled('form')``;
-
-export default Form;
diff --git a/static/app/components/deprecatedforms/genericField.spec.tsx b/static/app/components/deprecatedforms/genericField.spec.tsx
index e161e11ccfd604..88912dfd6ab505 100644
--- a/static/app/components/deprecatedforms/genericField.spec.tsx
+++ b/static/app/components/deprecatedforms/genericField.spec.tsx
@@ -1,7 +1,7 @@
import {render, screen} from 'sentry-test/reactTestingLibrary';
import {GenericField} from 'sentry/components/deprecatedforms/genericField';
-import FormState from 'sentry/components/forms/state';
+import {FormState} from 'sentry/components/forms/state';
describe('GenericField', () => {
it('renders text as TextInput', () => {
diff --git a/static/app/components/deprecatedforms/genericField.tsx b/static/app/components/deprecatedforms/genericField.tsx
index fedab19c273197..1885669ee71d68 100644
--- a/static/app/components/deprecatedforms/genericField.tsx
+++ b/static/app/components/deprecatedforms/genericField.tsx
@@ -8,7 +8,7 @@ import SelectCreatableField from 'sentry/components/deprecatedforms/selectCreata
import SelectField from 'sentry/components/deprecatedforms/selectField';
import TextareaField from 'sentry/components/deprecatedforms/textareaField';
import TextField from 'sentry/components/deprecatedforms/textField';
-import type FormState from 'sentry/components/forms/state';
+import type {FormState} from 'sentry/components/forms/state';
import {defined} from 'sentry/utils';
type FieldType =
diff --git a/static/app/components/deprecatedforms/inputField.tsx b/static/app/components/deprecatedforms/inputField.tsx
index 06bb8b18876080..572c63580c235e 100644
--- a/static/app/components/deprecatedforms/inputField.tsx
+++ b/static/app/components/deprecatedforms/inputField.tsx
@@ -22,7 +22,7 @@ type InputFieldProps = FormFieldProps & {
/**
* @deprecated Do not use this
*/
-abstract class InputField<
+export abstract class InputField<
Props extends InputFieldProps = InputFieldProps,
State extends FormField['state'] = FormField['state'],
> extends FormField {
@@ -56,5 +56,3 @@ abstract class InputField<
abstract getType(): string;
}
-
-export default InputField;
diff --git a/static/app/components/deprecatedforms/numberField.spec.tsx b/static/app/components/deprecatedforms/numberField.spec.tsx
index fcbefbd243bb2a..5c35b089248d50 100644
--- a/static/app/components/deprecatedforms/numberField.spec.tsx
+++ b/static/app/components/deprecatedforms/numberField.spec.tsx
@@ -1,6 +1,6 @@
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
-import Form from 'sentry/components/deprecatedforms/form';
+import {Form} from 'sentry/components/deprecatedforms/form';
import NumberField from 'sentry/components/deprecatedforms/numberField';
describe('NumberField', () => {
diff --git a/static/app/components/deprecatedforms/numberField.tsx b/static/app/components/deprecatedforms/numberField.tsx
index 7cd5a10b3f4519..4931fa8182b0ec 100644
--- a/static/app/components/deprecatedforms/numberField.tsx
+++ b/static/app/components/deprecatedforms/numberField.tsx
@@ -1,4 +1,4 @@
-import InputField from 'sentry/components/deprecatedforms/inputField';
+import {InputField} from 'sentry/components/deprecatedforms/inputField';
import {withFormContext} from 'sentry/components/deprecatedforms/withFormContext';
type Props = {
diff --git a/static/app/components/deprecatedforms/passwordField.spec.tsx b/static/app/components/deprecatedforms/passwordField.spec.tsx
index 45448c9030d5f3..c8b5f4a47f1de0 100644
--- a/static/app/components/deprecatedforms/passwordField.spec.tsx
+++ b/static/app/components/deprecatedforms/passwordField.spec.tsx
@@ -1,6 +1,6 @@
import {render} from 'sentry-test/reactTestingLibrary';
-import Form from 'sentry/components/deprecatedforms/form';
+import {Form} from 'sentry/components/deprecatedforms/form';
import PasswordField from 'sentry/components/deprecatedforms/passwordField';
describe('PasswordField', () => {
diff --git a/static/app/components/deprecatedforms/passwordField.tsx b/static/app/components/deprecatedforms/passwordField.tsx
index addfe3b8cd3ae9..717e57df055945 100644
--- a/static/app/components/deprecatedforms/passwordField.tsx
+++ b/static/app/components/deprecatedforms/passwordField.tsx
@@ -1,6 +1,6 @@
-import InputField from 'sentry/components/deprecatedforms/inputField';
+import {InputField} from 'sentry/components/deprecatedforms/inputField';
import {withFormContext} from 'sentry/components/deprecatedforms/withFormContext';
-import FormState from 'sentry/components/forms/state';
+import {FormState} from 'sentry/components/forms/state';
type Props = InputField['props'] & {
formState?: (typeof FormState)[keyof typeof FormState];
diff --git a/static/app/components/deprecatedforms/selectAsyncField.spec.tsx b/static/app/components/deprecatedforms/selectAsyncField.spec.tsx
index 56dec9caaf768a..b3fe139d5c5682 100644
--- a/static/app/components/deprecatedforms/selectAsyncField.spec.tsx
+++ b/static/app/components/deprecatedforms/selectAsyncField.spec.tsx
@@ -1,7 +1,7 @@
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import {selectEvent} from 'sentry-test/selectEvent';
-import Form from 'sentry/components/deprecatedforms/form';
+import {Form} from 'sentry/components/deprecatedforms/form';
import SelectAsyncField from 'sentry/components/deprecatedforms/selectAsyncField';
describe('SelectAsyncField', () => {
diff --git a/static/app/components/deprecatedforms/selectCreatableField.spec.tsx b/static/app/components/deprecatedforms/selectCreatableField.spec.tsx
index 5d32c5b44a13e0..385ffe0638f9cb 100644
--- a/static/app/components/deprecatedforms/selectCreatableField.spec.tsx
+++ b/static/app/components/deprecatedforms/selectCreatableField.spec.tsx
@@ -1,6 +1,6 @@
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
-import Form from 'sentry/components/deprecatedforms/form';
+import {Form} from 'sentry/components/deprecatedforms/form';
import SelectCreatableField from 'sentry/components/deprecatedforms/selectCreatableField';
describe('SelectCreatableField', () => {
diff --git a/static/app/components/deprecatedforms/selectField.spec.tsx b/static/app/components/deprecatedforms/selectField.spec.tsx
index e78091ae497f20..5d678887e962f0 100644
--- a/static/app/components/deprecatedforms/selectField.spec.tsx
+++ b/static/app/components/deprecatedforms/selectField.spec.tsx
@@ -1,7 +1,7 @@
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import {selectEvent} from 'sentry-test/selectEvent';
-import Form from 'sentry/components/deprecatedforms/form';
+import {Form} from 'sentry/components/deprecatedforms/form';
import SelectField from 'sentry/components/deprecatedforms/selectField';
describe('SelectField', () => {
diff --git a/static/app/components/deprecatedforms/textField.spec.tsx b/static/app/components/deprecatedforms/textField.spec.tsx
index b7e65e34c93b89..1444903a66acca 100644
--- a/static/app/components/deprecatedforms/textField.spec.tsx
+++ b/static/app/components/deprecatedforms/textField.spec.tsx
@@ -1,6 +1,6 @@
import {render} from 'sentry-test/reactTestingLibrary';
-import Form from 'sentry/components/deprecatedforms/form';
+import {Form} from 'sentry/components/deprecatedforms/form';
import TextField from 'sentry/components/deprecatedforms/textField';
describe('TextField', () => {
diff --git a/static/app/components/deprecatedforms/textField.tsx b/static/app/components/deprecatedforms/textField.tsx
index abf883dcad9d9b..d27685cfc5985b 100644
--- a/static/app/components/deprecatedforms/textField.tsx
+++ b/static/app/components/deprecatedforms/textField.tsx
@@ -1,4 +1,4 @@
-import InputField from 'sentry/components/deprecatedforms/inputField';
+import {InputField} from 'sentry/components/deprecatedforms/inputField';
import {withFormContext} from 'sentry/components/deprecatedforms/withFormContext';
type Props = InputField['props'] & {
diff --git a/static/app/components/deprecatedforms/textareaField.tsx b/static/app/components/deprecatedforms/textareaField.tsx
index 29c0d3e1b0bfcb..46476ce09df7c2 100644
--- a/static/app/components/deprecatedforms/textareaField.tsx
+++ b/static/app/components/deprecatedforms/textareaField.tsx
@@ -1,6 +1,6 @@
import {TextArea} from '@sentry/scraps/textarea';
-import InputField from 'sentry/components/deprecatedforms/inputField';
+import {InputField} from 'sentry/components/deprecatedforms/inputField';
import {withFormContext} from 'sentry/components/deprecatedforms/withFormContext';
type State = InputField['state'] & {
diff --git a/static/app/components/discover/transactionsList.spec.tsx b/static/app/components/discover/transactionsList.spec.tsx
index 31c6879ecbef5f..ba6bbca3017061 100644
--- a/static/app/components/discover/transactionsList.spec.tsx
+++ b/static/app/components/discover/transactionsList.spec.tsx
@@ -2,7 +2,7 @@ import {initializeOrg} from 'sentry-test/initializeOrg';
import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
import {TransactionsList} from 'sentry/components/discover/transactionsList';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MEPSettingProvider} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
import {OrganizationContext} from 'sentry/views/organizationContext';
diff --git a/static/app/components/discover/transactionsList.tsx b/static/app/components/discover/transactionsList.tsx
index 99984582644a05..fbd1b61a6acc5b 100644
--- a/static/app/components/discover/transactionsList.tsx
+++ b/static/app/components/discover/transactionsList.tsx
@@ -16,7 +16,7 @@ import {browserHistory} from 'sentry/utils/browserHistory';
import {DemoTourElement, DemoTourStep} from 'sentry/utils/demoMode/demoTours';
import type {TableDataRow} from 'sentry/utils/discover/discoverQuery';
import {DiscoverQuery} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {Sort} from 'sentry/utils/discover/fields';
import {SavedQueryDatasets} from 'sentry/utils/discover/types';
import {TrendsEventsDiscoverQuery} from 'sentry/utils/performance/trends/trendsDiscoverQuery';
diff --git a/static/app/components/discover/transactionsTable.tsx b/static/app/components/discover/transactionsTable.tsx
index d9fa81caf7bcdb..967bf22fb576ba 100644
--- a/static/app/components/discover/transactionsTable.tsx
+++ b/static/app/components/discover/transactionsTable.tsx
@@ -15,8 +15,7 @@ import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
import type {TableData, TableDataRow} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
-import type {MetaType} from 'sentry/utils/discover/eventView';
+import type {EventView, MetaType} from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import {fieldAlignment, getAggregateAlias} from 'sentry/utils/discover/fields';
import {ViewReplayLink} from 'sentry/utils/discover/viewReplayLink';
diff --git a/static/app/components/errorBoundary.spec.tsx b/static/app/components/errorBoundary.spec.tsx
index c0e64e06b046c7..56328a52119d96 100644
--- a/static/app/components/errorBoundary.spec.tsx
+++ b/static/app/components/errorBoundary.spec.tsx
@@ -1,6 +1,6 @@
import {render, screen} from 'sentry-test/reactTestingLibrary';
-import ErrorBoundary from './errorBoundary';
+import {ErrorBoundary} from './errorBoundary';
describe('ErrorBoundary', () => {
it('renders components', () => {
diff --git a/static/app/components/errorBoundary.tsx b/static/app/components/errorBoundary.tsx
index eea4086e40c48b..25712440cc4206 100644
--- a/static/app/components/errorBoundary.tsx
+++ b/static/app/components/errorBoundary.tsx
@@ -47,7 +47,7 @@ function getExclamation() {
return exclamation[Math.floor(Math.random() * exclamation.length)];
}
-class ErrorBoundary extends Component {
+export class ErrorBoundary extends Component {
static defaultProps: DefaultProps = {
mini: false,
};
@@ -167,5 +167,3 @@ const StackTrace = styled('pre')`
margin-left: 85px;
margin-right: 18px;
`;
-
-export default ErrorBoundary;
diff --git a/static/app/components/events/breadcrumbs/breadcrumbsDataSection.tsx b/static/app/components/events/breadcrumbs/breadcrumbsDataSection.tsx
index 7dddb5c486bde3..531a692d94c16c 100644
--- a/static/app/components/events/breadcrumbs/breadcrumbsDataSection.tsx
+++ b/static/app/components/events/breadcrumbs/breadcrumbsDataSection.tsx
@@ -5,7 +5,7 @@ import styled from '@emotion/styled';
import {Button} from '@sentry/scraps/button';
import {Grid} from '@sentry/scraps/layout';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {
BreadcrumbControlOptions,
BreadcrumbsDrawer,
diff --git a/static/app/components/events/breadcrumbs/breadcrumbsTimeline.tsx b/static/app/components/events/breadcrumbs/breadcrumbsTimeline.tsx
index 9954cf175b04e0..4cc825b78f2572 100644
--- a/static/app/components/events/breadcrumbs/breadcrumbsTimeline.tsx
+++ b/static/app/components/events/breadcrumbs/breadcrumbsTimeline.tsx
@@ -8,7 +8,7 @@ import {Tooltip} from '@sentry/scraps/tooltip';
import {DateTime} from 'sentry/components/dateTime';
import {Duration} from 'sentry/components/duration';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {BreadcrumbItemContent} from 'sentry/components/events/breadcrumbs/breadcrumbItemContent';
import type {EnhancedCrumb} from 'sentry/components/events/breadcrumbs/utils';
import {Timeline} from 'sentry/components/timeline';
diff --git a/static/app/components/events/contexts/contextBlock.tsx b/static/app/components/events/contexts/contextBlock.tsx
index fc649fda8d7c60..ea2ddc6cee7dd5 100644
--- a/static/app/components/events/contexts/contextBlock.tsx
+++ b/static/app/components/events/contexts/contextBlock.tsx
@@ -1,4 +1,4 @@
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {KeyValueList} from 'sentry/components/events/interfaces/keyValueList';
import type {KeyValueListData} from 'sentry/types/group';
diff --git a/static/app/components/events/contexts/contextCard.tsx b/static/app/components/events/contexts/contextCard.tsx
index 457f3971d47bc5..371f404a852fae 100644
--- a/static/app/components/events/contexts/contextCard.tsx
+++ b/static/app/components/events/contexts/contextCard.tsx
@@ -3,7 +3,7 @@ import startCase from 'lodash/startCase';
import {Flex} from '@sentry/scraps/layout';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import type {ContextValue} from 'sentry/components/events/contexts';
import {
getContextIcon,
diff --git a/static/app/components/events/contexts/contextDataSection.tsx b/static/app/components/events/contexts/contextDataSection.tsx
index 7df339d6b2f04a..70a8d04a0545f7 100644
--- a/static/app/components/events/contexts/contextDataSection.tsx
+++ b/static/app/components/events/contexts/contextDataSection.tsx
@@ -1,6 +1,6 @@
import {ExternalLink} from '@sentry/scraps/link';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {getOrderedContextItems} from 'sentry/components/events/contexts';
import {ContextCard} from 'sentry/components/events/contexts/contextCard';
import {CONTEXT_DOCS_LINK} from 'sentry/components/events/contexts/utils';
diff --git a/static/app/components/events/eventEntry.tsx b/static/app/components/events/eventEntry.tsx
index f508e2847f8325..02d12ca926a9af 100644
--- a/static/app/components/events/eventEntry.tsx
+++ b/static/app/components/events/eventEntry.tsx
@@ -1,4 +1,4 @@
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {EventBreadcrumbsSection} from 'sentry/components/events/eventBreadcrumbsSection';
import {t} from 'sentry/locale';
import type {Entry, Event, EventTransaction} from 'sentry/types/event';
diff --git a/static/app/components/events/eventHydrationDiff/replayDiffContent.tsx b/static/app/components/events/eventHydrationDiff/replayDiffContent.tsx
index fc8e9a3ce7598c..7c1f125f64add6 100644
--- a/static/app/components/events/eventHydrationDiff/replayDiffContent.tsx
+++ b/static/app/components/events/eventHydrationDiff/replayDiffContent.tsx
@@ -1,7 +1,7 @@
import styled from '@emotion/styled';
import {NegativeSpaceContainer} from 'sentry/components/container/negativeSpaceContainer';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {REPLAY_LOADING_HEIGHT} from 'sentry/components/events/eventReplay/constants';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {ArchivedReplayAlert} from 'sentry/components/replays/alerts/archivedReplayAlert';
diff --git a/static/app/components/events/eventHydrationDiff/replayDiffSection.tsx b/static/app/components/events/eventHydrationDiff/replayDiffSection.tsx
index 6cd8818c7e6c17..1c3a239abaf2b8 100644
--- a/static/app/components/events/eventHydrationDiff/replayDiffSection.tsx
+++ b/static/app/components/events/eventHydrationDiff/replayDiffSection.tsx
@@ -3,7 +3,7 @@ import ReactLazyLoad from 'react-lazyload';
import styled from '@emotion/styled';
import {NegativeSpaceContainer} from 'sentry/components/container/negativeSpaceContainer';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {REPLAY_LOADING_HEIGHT} from 'sentry/components/events/eventReplay/constants';
import {LazyLoad} from 'sentry/components/lazyLoad';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
diff --git a/static/app/components/events/eventReplay/index.tsx b/static/app/components/events/eventReplay/index.tsx
index 08c7c9c1d00a28..d356066fcb1b91 100644
--- a/static/app/components/events/eventReplay/index.tsx
+++ b/static/app/components/events/eventReplay/index.tsx
@@ -1,6 +1,6 @@
import {lazy} from 'react';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {ReplayClipSection} from 'sentry/components/events/eventReplay/replayClipSection';
import {LazyLoad} from 'sentry/components/lazyLoad';
import type {Event} from 'sentry/types/event';
diff --git a/static/app/components/events/eventReplay/replayClipSection.tsx b/static/app/components/events/eventReplay/replayClipSection.tsx
index 11db578c89311a..f2f2c87b35e648 100644
--- a/static/app/components/events/eventReplay/replayClipSection.tsx
+++ b/static/app/components/events/eventReplay/replayClipSection.tsx
@@ -4,7 +4,7 @@ import styled from '@emotion/styled';
import {LinkButton} from '@sentry/scraps/button';
import {NegativeSpaceContainer} from 'sentry/components/container/negativeSpaceContainer';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {REPLAY_LOADING_HEIGHT} from 'sentry/components/events/eventReplay/constants';
import {LazyLoad} from 'sentry/components/lazyLoad';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
diff --git a/static/app/components/events/eventReplay/replayPreviewPlayer.tsx b/static/app/components/events/eventReplay/replayPreviewPlayer.tsx
index b1bbdff68f7abe..ca903244f7f238 100644
--- a/static/app/components/events/eventReplay/replayPreviewPlayer.tsx
+++ b/static/app/components/events/eventReplay/replayPreviewPlayer.tsx
@@ -8,7 +8,7 @@ import {Button, LinkButton, type LinkButtonProps} from '@sentry/scraps/button';
import {Flex, Stack} from '@sentry/scraps/layout';
import {TooltipContext} from '@sentry/scraps/tooltip';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {useReplayContext} from 'sentry/components/replays/replayContext';
import {ReplayCurrentScreen} from 'sentry/components/replays/replayCurrentScreen';
import {ReplayCurrentUrl} from 'sentry/components/replays/replayCurrentUrl';
diff --git a/static/app/components/events/eventStatisticalDetector/breakpointChart.tsx b/static/app/components/events/eventStatisticalDetector/breakpointChart.tsx
index ee89577994cb9c..ae5ea5e5d17399 100644
--- a/static/app/components/events/eventStatisticalDetector/breakpointChart.tsx
+++ b/static/app/components/events/eventStatisticalDetector/breakpointChart.tsx
@@ -1,14 +1,14 @@
import {LinkButton} from '@sentry/scraps/button';
import {ChartType} from 'sentry/chartcuterie/types';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
import {t} from 'sentry/locale';
import type {Event} from 'sentry/types/event';
import type {EventsStatsData} from 'sentry/types/organization';
import {toArray} from 'sentry/utils/array/toArray';
import type {MetaType} from 'sentry/utils/discover/eventView';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import type {DiscoverQueryProps} from 'sentry/utils/discover/genericDiscoverQuery';
import {useGenericDiscoverQuery} from 'sentry/utils/discover/genericDiscoverQuery';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
diff --git a/static/app/components/events/eventStatisticalDetector/eventComparison/eventDisplay.tsx b/static/app/components/events/eventStatisticalDetector/eventComparison/eventDisplay.tsx
index 481191de5b8157..d3f128fe4828d1 100644
--- a/static/app/components/events/eventStatisticalDetector/eventComparison/eventDisplay.tsx
+++ b/static/app/components/events/eventStatisticalDetector/eventComparison/eventDisplay.tsx
@@ -18,7 +18,7 @@ import {
MINIMAP_HEIGHT,
MinimapBackground,
} from 'sentry/components/events/interfaces/spans/minimap';
-import WaterfallModel from 'sentry/components/events/interfaces/spans/waterfallModel';
+import {WaterfallModel} from 'sentry/components/events/interfaces/spans/waterfallModel';
import {OpsBreakdown} from 'sentry/components/events/opsBreakdown';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {TextOverflow} from 'sentry/components/textOverflow';
@@ -29,7 +29,7 @@ import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
import {useDiscoverQuery} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {generateLinkToEventInTraceView} from 'sentry/utils/discover/urls';
import {getShortEventId} from 'sentry/utils/events';
diff --git a/static/app/components/events/eventTags/eventTagsTree.tsx b/static/app/components/events/eventTags/eventTagsTree.tsx
index 1dff687343b31b..f328b7c0b2558b 100644
--- a/static/app/components/events/eventTags/eventTagsTree.tsx
+++ b/static/app/components/events/eventTags/eventTagsTree.tsx
@@ -1,7 +1,7 @@
import {Fragment, useMemo, useRef} from 'react';
import styled from '@emotion/styled';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {
EventTagsTreeRow,
type EventTagsTreeRowProps,
diff --git a/static/app/components/events/eventViewHierarchy.tsx b/static/app/components/events/eventViewHierarchy.tsx
index 8204a915135795..f3ea25b585b5c3 100644
--- a/static/app/components/events/eventViewHierarchy.tsx
+++ b/static/app/components/events/eventViewHierarchy.tsx
@@ -2,7 +2,7 @@ import {useMemo} from 'react';
import * as Sentry from '@sentry/react';
import {useFetchEventAttachments} from 'sentry/actionCreators/events';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {getAttachmentUrl} from 'sentry/components/events/attachmentViewers/utils';
import {
getPlatform,
diff --git a/static/app/components/events/eventXrayDiff.tsx b/static/app/components/events/eventXrayDiff.tsx
index 87a9c29ea9e3cd..ef81b4707fa93a 100644
--- a/static/app/components/events/eventXrayDiff.tsx
+++ b/static/app/components/events/eventXrayDiff.tsx
@@ -1,5 +1,5 @@
import {EmptyStateWarning} from 'sentry/components/emptyStateWarning';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {LoadingError} from 'sentry/components/loadingError';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {t} from 'sentry/locale';
diff --git a/static/app/components/events/highlights/highlightsDataSection.tsx b/static/app/components/events/highlights/highlightsDataSection.tsx
index c28a6dd5cfbd7b..04ff34a4898181 100644
--- a/static/app/components/events/highlights/highlightsDataSection.tsx
+++ b/static/app/components/events/highlights/highlightsDataSection.tsx
@@ -7,7 +7,7 @@ import {ExternalLink} from '@sentry/scraps/link';
import {openModal} from 'sentry/actionCreators/modal';
import {hasEveryAccess} from 'sentry/components/acl/access';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {ContextCardContent} from 'sentry/components/events/contexts/contextCard';
import {getContextMeta} from 'sentry/components/events/contexts/utils';
import {
diff --git a/static/app/components/events/interfaces/crashContent/exception/content.tsx b/static/app/components/events/interfaces/crashContent/exception/content.tsx
index 0b3193ed253aed..66b0a979536a00 100644
--- a/static/app/components/events/interfaces/crashContent/exception/content.tsx
+++ b/static/app/components/events/interfaces/crashContent/exception/content.tsx
@@ -5,7 +5,7 @@ import {Button} from '@sentry/scraps/button';
import {Container} from '@sentry/scraps/layout';
import {Tooltip} from '@sentry/scraps/tooltip';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {StacktraceBanners} from 'sentry/components/events/interfaces/crashContent/exception/banners/stacktraceBanners';
import {useLineCoverageContext} from 'sentry/components/events/interfaces/crashContent/exception/lineCoverageContext';
import {
diff --git a/static/app/components/events/interfaces/crashContent/exception/index.tsx b/static/app/components/events/interfaces/crashContent/exception/index.tsx
index e55825c28e8805..08fbbc82a3b176 100644
--- a/static/app/components/events/interfaces/crashContent/exception/index.tsx
+++ b/static/app/components/events/interfaces/crashContent/exception/index.tsx
@@ -1,4 +1,4 @@
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {useStacktraceContext} from 'sentry/components/events/interfaces/stackTraceContext';
import type {Event, ExceptionType} from 'sentry/types/event';
import type {Group} from 'sentry/types/group';
diff --git a/static/app/components/events/interfaces/crashContent/stackTrace/index.tsx b/static/app/components/events/interfaces/crashContent/stackTrace/index.tsx
index 129fca8516099e..73a6c278e7dc6b 100644
--- a/static/app/components/events/interfaces/crashContent/stackTrace/index.tsx
+++ b/static/app/components/events/interfaces/crashContent/stackTrace/index.tsx
@@ -1,6 +1,6 @@
import styled from '@emotion/styled';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import type {Event} from 'sentry/types/event';
import type {PlatformKey} from 'sentry/types/project';
import type {StacktraceType} from 'sentry/types/stacktrace';
diff --git a/static/app/components/events/interfaces/debugMeta/debugImageDetails/candidates.tsx b/static/app/components/events/interfaces/debugMeta/debugImageDetails/candidates.tsx
index ef7f4dd6629ffb..946de23e19bf16 100644
--- a/static/app/components/events/interfaces/debugMeta/debugImageDetails/candidates.tsx
+++ b/static/app/components/events/interfaces/debugMeta/debugImageDetails/candidates.tsx
@@ -49,7 +49,7 @@ type State = {
searchTerm: string;
};
-class Candidates extends Component {
+export class Candidates extends Component {
state: State = {
searchTerm: '',
filterOptions: [],
@@ -370,8 +370,6 @@ class Candidates extends Component {
}
}
-export default Candidates;
-
const Wrapper = styled('div')`
display: grid;
`;
diff --git a/static/app/components/events/interfaces/debugMeta/debugImageDetails/index.tsx b/static/app/components/events/interfaces/debugMeta/debugImageDetails/index.tsx
index 71f665fb567b70..20e013eda36216 100644
--- a/static/app/components/events/interfaces/debugMeta/debugImageDetails/index.tsx
+++ b/static/app/components/events/interfaces/debugMeta/debugImageDetails/index.tsx
@@ -26,7 +26,7 @@ import {useApi} from 'sentry/utils/useApi';
import {useOrganization} from 'sentry/utils/useOrganization';
import {getPrettyFileType} from 'sentry/views/settings/projectDebugFiles/utils';
-import Candidates from './candidates';
+import {Candidates} from './candidates';
import {GeneralInfo} from './generalInfo';
import {ReprocessAlert} from './reprocessAlert';
import {INTERNAL_SOURCE, INTERNAL_SOURCE_LOCATION} from './utils';
diff --git a/static/app/components/events/interfaces/exception.tsx b/static/app/components/events/interfaces/exception.tsx
index 81525a3b54b67c..28cdd1305b1fd5 100644
--- a/static/app/components/events/interfaces/exception.tsx
+++ b/static/app/components/events/interfaces/exception.tsx
@@ -1,7 +1,7 @@
import {Fragment} from 'react';
import {CommitRow} from 'sentry/components/commitRow';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {StacktraceContext} from 'sentry/components/events/interfaces/stackTraceContext';
import {SuspectCommits} from 'sentry/components/events/suspectCommits';
import {TraceEventDataSection} from 'sentry/components/events/traceEventDataSection';
diff --git a/static/app/components/events/interfaces/frame/deprecatedLine.tsx b/static/app/components/events/interfaces/frame/deprecatedLine.tsx
index 7cb66b96576f1f..8f666540d12f9b 100644
--- a/static/app/components/events/interfaces/frame/deprecatedLine.tsx
+++ b/static/app/components/events/interfaces/frame/deprecatedLine.tsx
@@ -8,7 +8,7 @@ import {Button} from '@sentry/scraps/button';
import InteractionStateLayer from '@sentry/scraps/interactionStateLayer';
import {openModal} from 'sentry/actionCreators/modal';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {analyzeFrameForRootCause} from 'sentry/components/events/interfaces/analyzeFrames';
import {LeadHint} from 'sentry/components/events/interfaces/frame/leadHint';
import {StacktraceLink} from 'sentry/components/events/interfaces/frame/stacktraceLink';
diff --git a/static/app/components/events/interfaces/nativeFrame.tsx b/static/app/components/events/interfaces/nativeFrame.tsx
index 3d47927cbda43b..e356ebbfca0552 100644
--- a/static/app/components/events/interfaces/nativeFrame.tsx
+++ b/static/app/components/events/interfaces/nativeFrame.tsx
@@ -8,7 +8,7 @@ import InteractionStateLayer from '@sentry/scraps/interactionStateLayer';
import {Flex} from '@sentry/scraps/layout';
import {Tooltip} from '@sentry/scraps/tooltip';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {FRAME_TOOLTIP_MAX_WIDTH} from 'sentry/components/events/interfaces/frame/defaultTitle';
import {OpenInContextLine} from 'sentry/components/events/interfaces/frame/openInContextLine';
import {StacktraceLink} from 'sentry/components/events/interfaces/frame/stacktraceLink';
diff --git a/static/app/components/events/interfaces/request/index.tsx b/static/app/components/events/interfaces/request/index.tsx
index 855760a97f1956..0803cab1dd2775 100644
--- a/static/app/components/events/interfaces/request/index.tsx
+++ b/static/app/components/events/interfaces/request/index.tsx
@@ -8,7 +8,7 @@ import {SegmentedControl} from '@sentry/scraps/segmentedControl';
import {Text} from '@sentry/scraps/text';
import {ClippedBox} from 'sentry/components/clippedBox';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {EventDataSection} from 'sentry/components/events/eventDataSection';
import {GraphQlRequestBody} from 'sentry/components/events/interfaces/request/graphQlRequestBody';
import {getCurlCommand, getFullUrl} from 'sentry/components/events/interfaces/utils';
diff --git a/static/app/components/events/interfaces/request/richHttpContentClippedBoxBodySection.tsx b/static/app/components/events/interfaces/request/richHttpContentClippedBoxBodySection.tsx
index 06f332e1096281..3f2f40293f1835 100644
--- a/static/app/components/events/interfaces/request/richHttpContentClippedBoxBodySection.tsx
+++ b/static/app/components/events/interfaces/request/richHttpContentClippedBoxBodySection.tsx
@@ -1,5 +1,5 @@
import {ClippedBox} from 'sentry/components/clippedBox';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {KeyValueList} from 'sentry/components/events/interfaces/keyValueList';
import {StructuredEventData} from 'sentry/components/structuredEventData';
import {JsonEventData} from 'sentry/components/structuredEventData/jsonEventData';
diff --git a/static/app/components/events/interfaces/request/richHttpContentClippedBoxKeyValueList.tsx b/static/app/components/events/interfaces/request/richHttpContentClippedBoxKeyValueList.tsx
index 646c6d1af9b5bf..56cfc23a7449ef 100644
--- a/static/app/components/events/interfaces/request/richHttpContentClippedBoxKeyValueList.tsx
+++ b/static/app/components/events/interfaces/request/richHttpContentClippedBoxKeyValueList.tsx
@@ -1,5 +1,5 @@
import {ClippedBox} from 'sentry/components/clippedBox';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {KeyValueList} from 'sentry/components/events/interfaces/keyValueList';
import type {EntryRequest} from 'sentry/types/event';
import type {Meta} from 'sentry/types/group';
diff --git a/static/app/components/events/interfaces/spans/spanTreeModel.spec.tsx b/static/app/components/events/interfaces/spans/spanTreeModel.spec.tsx
index 2ee80d32006a81..1bf2c0d1ec2287 100644
--- a/static/app/components/events/interfaces/spans/spanTreeModel.spec.tsx
+++ b/static/app/components/events/interfaces/spans/spanTreeModel.spec.tsx
@@ -1,6 +1,6 @@
import {waitFor} from 'sentry-test/reactTestingLibrary';
-import SpanTreeModel from 'sentry/components/events/interfaces/spans/spanTreeModel';
+import {SpanTreeModel} from 'sentry/components/events/interfaces/spans/spanTreeModel';
import type {
EnhancedProcessedSpanType,
RawSpanType,
@@ -607,7 +607,7 @@ describe('SpanTreeModel', () => {
// If statement here is required to avoid TS linting issues
if (spans[1]!.type === 'span_group_siblings') {
- expect(spans[1]!.spanSiblingGrouping!).toHaveLength(5);
+ expect(spans[1]!.spanSiblingGrouping).toHaveLength(5);
}
});
diff --git a/static/app/components/events/interfaces/spans/spanTreeModel.tsx b/static/app/components/events/interfaces/spans/spanTreeModel.tsx
index 40e6f5981b4fe2..1894714678ff56 100644
--- a/static/app/components/events/interfaces/spans/spanTreeModel.tsx
+++ b/static/app/components/events/interfaces/spans/spanTreeModel.tsx
@@ -34,7 +34,7 @@ import {
const MIN_SIBLING_GROUP_SIZE = 5;
-class SpanTreeModel {
+export class SpanTreeModel {
api: Client;
// readonly state
@@ -847,5 +847,3 @@ class SpanTreeModel {
};
};
}
-
-export default SpanTreeModel;
diff --git a/static/app/components/events/interfaces/spans/types.tsx b/static/app/components/events/interfaces/spans/types.tsx
index 824cb7ba9e529d..1acc38d15d6685 100644
--- a/static/app/components/events/interfaces/spans/types.tsx
+++ b/static/app/components/events/interfaces/spans/types.tsx
@@ -1,6 +1,6 @@
import type {Fuse} from 'sentry/utils/fuzzySearch';
-import type SpanTreeModel from './spanTreeModel';
+import type {SpanTreeModel} from './spanTreeModel';
export type GapSpanType = {
isOrphan: boolean;
diff --git a/static/app/components/events/interfaces/spans/utils.tsx b/static/app/components/events/interfaces/spans/utils.tsx
index e37285992d726f..34625c4a442603 100644
--- a/static/app/components/events/interfaces/spans/utils.tsx
+++ b/static/app/components/events/interfaces/spans/utils.tsx
@@ -13,7 +13,7 @@ import type {
import {EntryType} from 'sentry/types/event';
import {assert} from 'sentry/types/utils';
-import type SpanTreeModel from './spanTreeModel';
+import type {SpanTreeModel} from './spanTreeModel';
import type {
AggregateSpanType,
GapSpanType,
diff --git a/static/app/components/events/interfaces/spans/waterfallModel.spec.tsx b/static/app/components/events/interfaces/spans/waterfallModel.spec.tsx
index 72bdb31a948427..06e213a28bc52a 100644
--- a/static/app/components/events/interfaces/spans/waterfallModel.spec.tsx
+++ b/static/app/components/events/interfaces/spans/waterfallModel.spec.tsx
@@ -1,7 +1,7 @@
import type {ActiveFilter} from 'sentry/components/events/interfaces/spans/filter';
import {noFilter} from 'sentry/components/events/interfaces/spans/filter';
import type {EnhancedProcessedSpanType} from 'sentry/components/events/interfaces/spans/types';
-import WaterfallModel from 'sentry/components/events/interfaces/spans/waterfallModel';
+import {WaterfallModel} from 'sentry/components/events/interfaces/spans/waterfallModel';
import type {EventTransaction} from 'sentry/types/event';
import {EntryType} from 'sentry/types/event';
import {assert} from 'sentry/types/utils';
diff --git a/static/app/components/events/interfaces/spans/waterfallModel.tsx b/static/app/components/events/interfaces/spans/waterfallModel.tsx
index 309f8575865003..042ffb5ee5bbae 100644
--- a/static/app/components/events/interfaces/spans/waterfallModel.tsx
+++ b/static/app/components/events/interfaces/spans/waterfallModel.tsx
@@ -9,7 +9,7 @@ import {createFuzzySearch} from 'sentry/utils/fuzzySearch';
import type {ActiveOperationFilter} from './filter';
import {noFilter, toggleAllFilters, toggleFilter} from './filter';
-import SpanTreeModel from './spanTreeModel';
+import {SpanTreeModel} from './spanTreeModel';
import type {
EnhancedProcessedSpanType,
FilterSpans,
@@ -21,7 +21,7 @@ import type {
} from './types';
import {boundsGenerator, generateRootSpan, getSpanID, parseTrace} from './utils';
-class WaterfallModel {
+export class WaterfallModel {
api: Client = new Client();
// readonly state
@@ -356,5 +356,3 @@ class WaterfallModel {
});
};
}
-
-export default WaterfallModel;
diff --git a/static/app/components/events/interfaces/threads.tsx b/static/app/components/events/interfaces/threads.tsx
index 6ba512e40688c3..593aeb24b2a58d 100644
--- a/static/app/components/events/interfaces/threads.tsx
+++ b/static/app/components/events/interfaces/threads.tsx
@@ -5,7 +5,7 @@ import {Button, ButtonBar} from '@sentry/scraps/button';
import {Flex} from '@sentry/scraps/layout';
import {CommitRow} from 'sentry/components/commitRow';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {
StacktraceContext,
useStacktraceContext,
diff --git a/static/app/components/feedback/feedbackItem/feedbackActions.tsx b/static/app/components/feedback/feedbackItem/feedbackActions.tsx
index e64feca2f18304..6289a92c5e3fac 100644
--- a/static/app/components/feedback/feedbackItem/feedbackActions.tsx
+++ b/static/app/components/feedback/feedbackItem/feedbackActions.tsx
@@ -6,7 +6,7 @@ import {Flex} from '@sentry/scraps/layout';
import {Tooltip} from '@sentry/scraps/tooltip';
import {DropdownMenu} from 'sentry/components/dropdownMenu';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {FeedbackAssignedTo} from 'sentry/components/feedback/feedbackItem/feedbackAssignedTo';
import {useFeedbackActions} from 'sentry/components/feedback/feedbackItem/useFeedbackActions';
import {IconCopy, IconEllipsis} from 'sentry/icons';
diff --git a/static/app/components/feedback/feedbackItem/feedbackItem.tsx b/static/app/components/feedback/feedbackItem/feedbackItem.tsx
index b88ab29990baf3..8cb117b0886408 100644
--- a/static/app/components/feedback/feedbackItem/feedbackItem.tsx
+++ b/static/app/components/feedback/feedbackItem/feedbackItem.tsx
@@ -2,7 +2,7 @@ import {Fragment, useEffect, useMemo, useRef} from 'react';
import styled from '@emotion/styled';
import {AnalyticsArea} from 'sentry/components/analyticsArea';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {getOrderedContextItems} from 'sentry/components/events/contexts';
import {ContextCard} from 'sentry/components/events/contexts/contextCard';
import {EventTagsTree} from 'sentry/components/events/eventTags/eventTagsTree';
diff --git a/static/app/components/feedback/feedbackItem/feedbackItemHeader.tsx b/static/app/components/feedback/feedbackItem/feedbackItemHeader.tsx
index cb32a3b88c0a9b..ab87b8a395250c 100644
--- a/static/app/components/feedback/feedbackItem/feedbackItemHeader.tsx
+++ b/static/app/components/feedback/feedbackItem/feedbackItemHeader.tsx
@@ -4,7 +4,7 @@ import styled from '@emotion/styled';
import {Button} from '@sentry/scraps/button';
import {Flex} from '@sentry/scraps/layout';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {FeedbackActions} from 'sentry/components/feedback/feedbackItem/feedbackActions';
import {FeedbackShortId} from 'sentry/components/feedback/feedbackItem/feedbackShortId';
import {FeedbackViewers} from 'sentry/components/feedback/feedbackItem/feedbackViewers';
diff --git a/static/app/components/feedback/feedbackItem/feedbackItemLoader.tsx b/static/app/components/feedback/feedbackItem/feedbackItemLoader.tsx
index 51b51a907de38e..07ae5a5486978c 100644
--- a/static/app/components/feedback/feedbackItem/feedbackItemLoader.tsx
+++ b/static/app/components/feedback/feedbackItem/feedbackItemLoader.tsx
@@ -1,6 +1,6 @@
import {useEffect} from 'react';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {FeedbackEmptyDetails} from 'sentry/components/feedback/details/feedbackEmptyDetails';
import {FeedbackErrorDetails} from 'sentry/components/feedback/details/feedbackErrorDetails';
import {FeedbackItem} from 'sentry/components/feedback/feedbackItem/feedbackItem';
diff --git a/static/app/components/feedback/feedbackItem/feedbackReplay.tsx b/static/app/components/feedback/feedbackItem/feedbackReplay.tsx
index 84aa2bb573fea7..632f57ebcef1f5 100644
--- a/static/app/components/feedback/feedbackItem/feedbackReplay.tsx
+++ b/static/app/components/feedback/feedbackItem/feedbackReplay.tsx
@@ -1,4 +1,4 @@
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {FeedbackItemSection} from 'sentry/components/feedback/feedbackItem/feedbackItemSection';
import {ReplayInlineCTAPanel} from 'sentry/components/feedback/feedbackItem/replayInlineCTAPanel';
import {ReplaySection} from 'sentry/components/feedback/feedbackItem/replaySection';
diff --git a/static/app/components/feedback/list/feedbackList.tsx b/static/app/components/feedback/list/feedbackList.tsx
index f7eff63c352788..d7500de50dd00f 100644
--- a/static/app/components/feedback/list/feedbackList.tsx
+++ b/static/app/components/feedback/list/feedbackList.tsx
@@ -8,7 +8,7 @@ import {Stack} from '@sentry/scraps/layout';
import {Tooltip} from '@sentry/scraps/tooltip';
import type {ApiResult} from 'sentry/api';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {FeedbackListHeader} from 'sentry/components/feedback/list/feedbackListHeader';
import {FeedbackListItem} from 'sentry/components/feedback/list/feedbackListItem';
import {useFeedbackQueryKeys} from 'sentry/components/feedback/useFeedbackQueryKeys';
diff --git a/static/app/components/feedback/list/feedbackListBulkSelection.tsx b/static/app/components/feedback/list/feedbackListBulkSelection.tsx
index 3c8e5b338dcb6a..219694163da955 100644
--- a/static/app/components/feedback/list/feedbackListBulkSelection.tsx
+++ b/static/app/components/feedback/list/feedbackListBulkSelection.tsx
@@ -2,7 +2,7 @@ import {Button} from '@sentry/scraps/button';
import {Flex} from '@sentry/scraps/layout';
import {DropdownMenu} from 'sentry/components/dropdownMenu';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {useBulkEditFeedbacks} from 'sentry/components/feedback/list/useBulkEditFeedbacks';
import type {Mailbox} from 'sentry/components/feedback/useMailbox';
import {IconEllipsis} from 'sentry/icons/iconEllipsis';
diff --git a/static/app/components/forms/formField/controlState.tsx b/static/app/components/forms/formField/controlState.tsx
index 10b6fe05bae464..ec9f231cc519aa 100644
--- a/static/app/components/forms/formField/controlState.tsx
+++ b/static/app/components/forms/formField/controlState.tsx
@@ -2,7 +2,7 @@ import {Observer} from 'mobx-react-lite';
import {ControlState} from 'sentry/components/forms/fieldGroup/controlState';
import type {FormModel} from 'sentry/components/forms/model';
-import FormState from 'sentry/components/forms/state';
+import {FormState} from 'sentry/components/forms/state';
type Props = {
model: FormModel;
diff --git a/static/app/components/forms/formField/index.tsx b/static/app/components/forms/formField/index.tsx
index 4b8967e5598415..7a76ed94968131 100644
--- a/static/app/components/forms/formField/index.tsx
+++ b/static/app/components/forms/formField/index.tsx
@@ -17,7 +17,7 @@ import type {FieldGroupProps} from 'sentry/components/forms/fieldGroup/types';
import {FormContext} from 'sentry/components/forms/formContext';
import type {FormModel} from 'sentry/components/forms/model';
import {MockModel} from 'sentry/components/forms/model';
-import FormState from 'sentry/components/forms/state';
+import {FormState} from 'sentry/components/forms/state';
import type {FieldValue} from 'sentry/components/forms/types';
import {PanelAlert} from 'sentry/components/panels/panelAlert';
import {t} from 'sentry/locale';
diff --git a/static/app/components/forms/model.tsx b/static/app/components/forms/model.tsx
index e92ff45f9733a1..9a6efbfbc13204 100644
--- a/static/app/components/forms/model.tsx
+++ b/static/app/components/forms/model.tsx
@@ -5,7 +5,7 @@ import {action, computed, makeObservable, observable} from 'mobx';
import {addErrorMessage} from 'sentry/actionCreators/indicator';
import {Client} from 'sentry/api';
import {addUndoableFormChangeMessage} from 'sentry/components/forms/formIndicators';
-import FormState from 'sentry/components/forms/state';
+import {FormState} from 'sentry/components/forms/state';
import {t} from 'sentry/locale';
import type {Choice} from 'sentry/types/core';
import {defined} from 'sentry/utils';
diff --git a/static/app/components/forms/state.tsx b/static/app/components/forms/state.tsx
index 4602f21746327e..2ad48b6acf9cbe 100644
--- a/static/app/components/forms/state.tsx
+++ b/static/app/components/forms/state.tsx
@@ -1,4 +1,4 @@
-enum FormState {
+export enum FormState {
HOVER = 'Hover',
DISABLED = 'Disabled',
LOADING = 'Loading',
@@ -7,5 +7,3 @@ enum FormState {
ERROR = 'Error',
INCOMPLETE = 'Incomplete',
}
-
-export default FormState;
diff --git a/static/app/components/globalDrawer/index.tsx b/static/app/components/globalDrawer/index.tsx
index 271d527d9b322e..cc0b5c354aed76 100644
--- a/static/app/components/globalDrawer/index.tsx
+++ b/static/app/components/globalDrawer/index.tsx
@@ -13,7 +13,7 @@ import type {Location} from 'history';
import {useScrollLock} from '@sentry/scraps/useScrollLock';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {DrawerComponents} from 'sentry/components/globalDrawer/components';
import {t} from 'sentry/locale';
import {defined} from 'sentry/utils';
diff --git a/static/app/components/group/externalIssuesList/index.tsx b/static/app/components/group/externalIssuesList/index.tsx
index ac0d0108a11e73..e4d42b65a56583 100644
--- a/static/app/components/group/externalIssuesList/index.tsx
+++ b/static/app/components/group/externalIssuesList/index.tsx
@@ -7,7 +7,7 @@ import {Tooltip} from '@sentry/scraps/tooltip';
import {DropdownButton} from 'sentry/components/dropdownButton';
import {DropdownMenu} from 'sentry/components/dropdownMenu';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import type {ExternalIssueAction} from 'sentry/components/group/externalIssuesList/hooks/types';
import {useGroupExternalIssues} from 'sentry/components/group/externalIssuesList/hooks/useGroupExternalIssues';
import {Placeholder} from 'sentry/components/placeholder';
diff --git a/static/app/components/groupHeaderRow.tsx b/static/app/components/groupHeaderRow.tsx
index 8dd17a27fd8c8e..b7d8174b14afa0 100644
--- a/static/app/components/groupHeaderRow.tsx
+++ b/static/app/components/groupHeaderRow.tsx
@@ -4,7 +4,7 @@ import {useHover} from '@react-aria/interactions';
import {Link} from '@sentry/scraps/link';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {EventMessage} from 'sentry/components/events/eventMessage';
import {GroupTitle} from 'sentry/components/groupTitle';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
diff --git a/static/app/components/idBadge/index.tsx b/static/app/components/idBadge/index.tsx
index eea81d80d035e3..c4c273addd5d3f 100644
--- a/static/app/components/idBadge/index.tsx
+++ b/static/app/components/idBadge/index.tsx
@@ -1,6 +1,6 @@
import styled from '@emotion/styled';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import type {GetBadgeProps} from './getBadge';
import {getBadge} from './getBadge';
diff --git a/static/app/components/links/externalLink.tsx b/static/app/components/links/externalLink.tsx
index 12e1ceb35f03f4..2a1b9bcf34c86b 100644
--- a/static/app/components/links/externalLink.tsx
+++ b/static/app/components/links/externalLink.tsx
@@ -1,6 +1,8 @@
import {ExternalLink} from '@sentry/scraps/link';
-/**
- * @deprecated Use `ExternalLink` from `@sentry/scraps/link` instead.
- */
-export default ExternalLink;
+export {
+ /**
+ * @deprecated Use `ExternalLink` from `@sentry/scraps/link` instead.
+ */
+ ExternalLink,
+};
diff --git a/static/app/components/modals/dataWidgetViewerModal.spec.tsx b/static/app/components/modals/dataWidgetViewerModal.spec.tsx
index 87a102ef2c42f9..9c6b9f841921a1 100644
--- a/static/app/components/modals/dataWidgetViewerModal.spec.tsx
+++ b/static/app/components/modals/dataWidgetViewerModal.spec.tsx
@@ -24,7 +24,7 @@ import {ProjectsStore} from 'sentry/stores/projectsStore';
import type {DashboardFilters, Widget, WidgetQuery} from 'sentry/views/dashboards/types';
import {DisplayType, WidgetType} from 'sentry/views/dashboards/types';
import {performanceScoreTooltip} from 'sentry/views/dashboards/utils';
-import WidgetLegendSelectionState from 'sentry/views/dashboards/widgetLegendSelectionState';
+import {WidgetLegendSelectionState} from 'sentry/views/dashboards/widgetLegendSelectionState';
jest.mock('echarts-for-react/lib/core', () => {
return jest.fn(({style}) => {
diff --git a/static/app/components/modals/dataWidgetViewerModal.tsx b/static/app/components/modals/dataWidgetViewerModal.tsx
index 13a1c9f18d41cc..d759c0c0f782aa 100644
--- a/static/app/components/modals/dataWidgetViewerModal.tsx
+++ b/static/app/components/modals/dataWidgetViewerModal.tsx
@@ -31,8 +31,7 @@ import {defined} from 'sentry/utils';
import {CAN_MARK, trackAnalytics} from 'sentry/utils/analytics';
import {getUtcDateString} from 'sentry/utils/dates';
import type {TableDataWithTitle} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
-import type {MetaType} from 'sentry/utils/discover/eventView';
+import type {EventView, MetaType} from 'sentry/utils/discover/eventView';
import type {RenderFunctionBaggage} from 'sentry/utils/discover/fieldRenderers';
import type {Sort} from 'sentry/utils/discover/fields';
import {
@@ -105,7 +104,7 @@ import {ReleaseWidgetQueries} from 'sentry/views/dashboards/widgetCard/releaseWi
import {VisualizationWidget} from 'sentry/views/dashboards/widgetCard/visualizationWidget';
import {WidgetCardChartContainer} from 'sentry/views/dashboards/widgetCard/widgetCardChartContainer';
import {WidgetQueries} from 'sentry/views/dashboards/widgetCard/widgetQueries';
-import type WidgetLegendSelectionState from 'sentry/views/dashboards/widgetLegendSelectionState';
+import type {WidgetLegendSelectionState} from 'sentry/views/dashboards/widgetLegendSelectionState';
import {AgentsTracesTableWidgetVisualization} from 'sentry/views/dashboards/widgets/agentsTracesTableWidget/agentsTracesTableWidgetVisualization';
import {ALLOWED_CELL_ACTIONS} from 'sentry/views/dashboards/widgets/common/settings';
import {TableWidgetVisualization} from 'sentry/views/dashboards/widgets/tableWidget/tableWidgetVisualization';
diff --git a/static/app/components/modals/featureTourModal.spec.tsx b/static/app/components/modals/featureTourModal.spec.tsx
index 862b279e1dee7e..f74651fe510eef 100644
--- a/static/app/components/modals/featureTourModal.spec.tsx
+++ b/static/app/components/modals/featureTourModal.spec.tsx
@@ -3,7 +3,7 @@ import {Fragment} from 'react';
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import {GlobalModal} from 'sentry/components/globalModal';
-import FeatureTourModal from 'sentry/components/modals/featureTourModal';
+import {FeatureTourModal} from 'sentry/components/modals/featureTourModal';
const steps = [
{
diff --git a/static/app/components/modals/featureTourModal.tsx b/static/app/components/modals/featureTourModal.tsx
index 66518ef59f0e84..3394909dcc4ece 100644
--- a/static/app/components/modals/featureTourModal.tsx
+++ b/static/app/components/modals/featureTourModal.tsx
@@ -72,7 +72,7 @@ const defaultProps = {
* trigger re-renders in the modal contents. This requires a bit of duplicate state
* to be managed around the current step.
*/
-class FeatureTourModal extends Component {
+export class FeatureTourModal extends Component {
static defaultProps = defaultProps;
state: State = {
@@ -122,8 +122,6 @@ class FeatureTourModal extends Component {
}
}
-export default FeatureTourModal;
-
type ContentsProps = ModalRenderProps &
Pick &
Pick;
diff --git a/static/app/components/modals/inviteMembersModal/index.tsx b/static/app/components/modals/inviteMembersModal/index.tsx
index 1af8c20d916059..bf8db823c4b839 100644
--- a/static/app/components/modals/inviteMembersModal/index.tsx
+++ b/static/app/components/modals/inviteMembersModal/index.tsx
@@ -2,7 +2,7 @@ import {css} from '@emotion/react';
import styled from '@emotion/styled';
import type {ModalRenderProps} from 'sentry/actionCreators/modal';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {LoadingError} from 'sentry/components/loadingError';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {
diff --git a/static/app/components/modals/textWidgetViewerModal.spec.tsx b/static/app/components/modals/textWidgetViewerModal.spec.tsx
index acfff6760650e3..5db4a7ff8040f6 100644
--- a/static/app/components/modals/textWidgetViewerModal.spec.tsx
+++ b/static/app/components/modals/textWidgetViewerModal.spec.tsx
@@ -13,7 +13,7 @@ import {ConfigStore} from 'sentry/stores/configStore';
import {trackAnalytics} from 'sentry/utils/analytics';
import {DisplayType} from 'sentry/views/dashboards/types';
import type {DashboardPermissions, Widget} from 'sentry/views/dashboards/types';
-import WidgetLegendSelectionState from 'sentry/views/dashboards/widgetLegendSelectionState';
+import {WidgetLegendSelectionState} from 'sentry/views/dashboards/widgetLegendSelectionState';
jest.mock('sentry/utils/analytics');
diff --git a/static/app/components/modals/textWidgetViewerModal.tsx b/static/app/components/modals/textWidgetViewerModal.tsx
index fdef1349dd3171..757f133064c9a7 100644
--- a/static/app/components/modals/textWidgetViewerModal.tsx
+++ b/static/app/components/modals/textWidgetViewerModal.tsx
@@ -21,7 +21,7 @@ import type {
} from 'sentry/views/dashboards/types';
import {checkUserHasEditAccess} from 'sentry/views/dashboards/utils/checkUserHasEditAccess';
import {WidgetCardChartContainer} from 'sentry/views/dashboards/widgetCard/widgetCardChartContainer';
-import type WidgetLegendSelectionState from 'sentry/views/dashboards/widgetLegendSelectionState';
+import type {WidgetLegendSelectionState} from 'sentry/views/dashboards/widgetLegendSelectionState';
interface TextWidgetViewerModalOptions {
organization: Organization;
diff --git a/static/app/components/modals/widgetBuilder/addToDashboardModal.tsx b/static/app/components/modals/widgetBuilder/addToDashboardModal.tsx
index 61173a94b813b8..603661dfe74285 100644
--- a/static/app/components/modals/widgetBuilder/addToDashboardModal.tsx
+++ b/static/app/components/modals/widgetBuilder/addToDashboardModal.tsx
@@ -70,7 +70,7 @@ import {convertWidgetToQueryParams} from 'sentry/views/dashboards/widgetBuilder/
import WidgetCard from 'sentry/views/dashboards/widgetCard';
import {DashboardsMEPProvider} from 'sentry/views/dashboards/widgetCard/dashboardsMEPContext';
import {WidgetLegendNameEncoderDecoder} from 'sentry/views/dashboards/widgetLegendNameEncoderDecoder';
-import WidgetLegendSelectionState from 'sentry/views/dashboards/widgetLegendSelectionState';
+import {WidgetLegendSelectionState} from 'sentry/views/dashboards/widgetLegendSelectionState';
import {getTopNConvertedDefaultWidgets} from 'sentry/views/dashboards/widgetLibrary/data';
import type {TabularColumn} from 'sentry/views/dashboards/widgets/common/types';
import {MetricsDataSwitcher} from 'sentry/views/performance/landing/metricsDataSwitcher';
diff --git a/static/app/components/onboarding/consoleModal.tsx b/static/app/components/onboarding/consoleModal.tsx
index e02f1ead309e7b..4b42ca411b2280 100644
--- a/static/app/components/onboarding/consoleModal.tsx
+++ b/static/app/components/onboarding/consoleModal.tsx
@@ -8,7 +8,7 @@ import {Flex} from '@sentry/scraps/layout';
import {Heading} from '@sentry/scraps/text';
import type {ModalRenderProps} from 'sentry/actionCreators/modal';
-import ExternalLink from 'sentry/components/links/externalLink';
+import {ExternalLink} from 'sentry/components/links/externalLink';
import {ConsolePlatform} from 'sentry/constants/consolePlatforms';
import {t, tct} from 'sentry/locale';
import type {OnboardingSelectedSDK} from 'sentry/types/onboarding';
diff --git a/static/app/components/performance/searchBar.spec.tsx b/static/app/components/performance/searchBar.spec.tsx
index f0a4a982fe78db..2fa974e554916c 100644
--- a/static/app/components/performance/searchBar.spec.tsx
+++ b/static/app/components/performance/searchBar.spec.tsx
@@ -6,7 +6,7 @@ import {textWithMarkupMatcher} from 'sentry-test/utils';
import type {SearchBarProps} from 'sentry/components/performance/searchBar';
import {SearchBar} from 'sentry/components/performance/searchBar';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
describe('SearchBar', () => {
diff --git a/static/app/components/performance/searchBar.tsx b/static/app/components/performance/searchBar.tsx
index d88d931fe2099e..19c6db2a2682a7 100644
--- a/static/app/components/performance/searchBar.tsx
+++ b/static/app/components/performance/searchBar.tsx
@@ -11,7 +11,7 @@ import {DEFAULT_DEBOUNCE_DURATION} from 'sentry/constants';
import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {doDiscoverQuery} from 'sentry/utils/discover/genericDiscoverQuery';
import {parsePeriodToHours} from 'sentry/utils/duration/parsePeriodToHours';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
diff --git a/static/app/components/profiling/profileEventsTable.tsx b/static/app/components/profiling/profileEventsTable.tsx
index 7cb526aa7aa858..23aa26d2648507 100644
--- a/static/app/components/profiling/profileEventsTable.tsx
+++ b/static/app/components/profiling/profileEventsTable.tsx
@@ -20,7 +20,7 @@ import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
import {getTimeStampFromTableDateField} from 'sentry/utils/dates';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DURATION_UNITS} from 'sentry/utils/discover/fieldRenderers';
import {Container, NumberContainer} from 'sentry/utils/discover/styles';
import {generateLinkToEventInTraceView} from 'sentry/utils/discover/urls';
diff --git a/static/app/components/profiling/suspectFunctions/suspectFunctionsTable.tsx b/static/app/components/profiling/suspectFunctions/suspectFunctionsTable.tsx
index 9b405c63b580a9..43f2a3a46965a2 100644
--- a/static/app/components/profiling/suspectFunctions/suspectFunctionsTable.tsx
+++ b/static/app/components/profiling/suspectFunctions/suspectFunctionsTable.tsx
@@ -16,7 +16,7 @@ import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {RenderFunctionBaggage} from 'sentry/utils/discover/fieldRenderers';
import {FIELD_FORMATTERS} from 'sentry/utils/discover/fieldRenderers';
import {getShortEventId} from 'sentry/utils/events';
diff --git a/static/app/components/quickTrace/utils.tsx b/static/app/components/quickTrace/utils.tsx
index 33cfd85624b097..31b74c3006f1f4 100644
--- a/static/app/components/quickTrace/utils.tsx
+++ b/static/app/components/quickTrace/utils.tsx
@@ -8,7 +8,7 @@ import {ALL_ACCESS_PROJECTS} from 'sentry/components/pageFilters/constants';
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
import type {Event, EventTransaction} from 'sentry/types/event';
import type {Organization} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {SavedQueryDatasets} from 'sentry/utils/discover/types';
import {hasDatasetSelector} from 'sentry/views/dashboards/utils';
import type {TraceViewSources} from 'sentry/views/performance/newTraceDetails/traceHeader/breadcrumbs';
diff --git a/static/app/components/replays/breadcrumbs/breadcrumbItem.tsx b/static/app/components/replays/breadcrumbs/breadcrumbItem.tsx
index 25c7fced9525ac..a84feeb02bc3a5 100644
--- a/static/app/components/replays/breadcrumbs/breadcrumbItem.tsx
+++ b/static/app/components/replays/breadcrumbs/breadcrumbItem.tsx
@@ -3,7 +3,7 @@ import {isValidElement, useEffect, useRef} from 'react';
import {useTheme} from '@emotion/react';
import styled from '@emotion/styled';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {BreadcrumbCodeSnippet} from 'sentry/components/replays/breadcrumbs/breadcrumbCodeSnippet';
import {BreadcrumbComparisonButton} from 'sentry/components/replays/breadcrumbs/breadcrumbComparisonButton';
import {BreadcrumbDescription} from 'sentry/components/replays/breadcrumbs/breadcrumbDescription';
diff --git a/static/app/components/replays/header/replayMetaData.tsx b/static/app/components/replays/header/replayMetaData.tsx
index e022d49c40006a..da2a938dea56bb 100644
--- a/static/app/components/replays/header/replayMetaData.tsx
+++ b/static/app/components/replays/header/replayMetaData.tsx
@@ -8,7 +8,7 @@ import {ErrorCounts} from 'sentry/components/replays/header/errorCounts';
import {ReplayViewers} from 'sentry/components/replays/header/replayViewers';
import {IconCursorArrow} from 'sentry/icons';
import {t} from 'sentry/locale';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {getRouteStringFromRoutes} from 'sentry/utils/getRouteStringFromRoutes';
import {TabKey} from 'sentry/utils/replays/hooks/useActiveReplayTab';
import type {RawReplayError} from 'sentry/utils/replays/types';
diff --git a/static/app/components/replays/list/__stories__/replayList.tsx b/static/app/components/replays/list/__stories__/replayList.tsx
index 18e628a06fd310..80904b65388bf6 100644
--- a/static/app/components/replays/list/__stories__/replayList.tsx
+++ b/static/app/components/replays/list/__stories__/replayList.tsx
@@ -7,7 +7,7 @@ import {Container} from '@sentry/scraps/layout';
import {Tooltip} from '@sentry/scraps/tooltip';
import type {ApiResult} from 'sentry/api';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {InfiniteListItems} from 'sentry/components/infiniteList/infiniteListItems';
import {InfiniteListState} from 'sentry/components/infiniteList/infiniteListState';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
diff --git a/static/app/components/replays/replayTagsTableRow.tsx b/static/app/components/replays/replayTagsTableRow.tsx
index 84b6f31152dced..c8497ad428afc6 100644
--- a/static/app/components/replays/replayTagsTableRow.tsx
+++ b/static/app/components/replays/replayTagsTableRow.tsx
@@ -6,7 +6,7 @@ import type {LocationDescriptor} from 'history';
import {Link} from '@sentry/scraps/link';
import {Tooltip} from '@sentry/scraps/tooltip';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {AnnotatedText} from 'sentry/components/events/meta/annotatedText';
import {KeyValueTableRow} from 'sentry/components/keyValueTable';
import {ReleaseDropdownFilter} from 'sentry/components/replays/releaseDropdownFilter';
diff --git a/static/app/components/replays/replayView.tsx b/static/app/components/replays/replayView.tsx
index fd1386d56fd3d6..c53301fba79f7a 100644
--- a/static/app/components/replays/replayView.tsx
+++ b/static/app/components/replays/replayView.tsx
@@ -6,7 +6,7 @@ import {ExternalLink} from '@sentry/scraps/link';
import {Tooltip} from '@sentry/scraps/tooltip';
import {NegativeSpaceContainer} from 'sentry/components/container/negativeSpaceContainer';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {QuestionTooltip} from 'sentry/components/questionTooltip';
import {CanvasSupportNotice} from 'sentry/components/replays/canvasSupportNotice';
import {
diff --git a/static/app/components/replays/table/deleteReplays.tsx b/static/app/components/replays/table/deleteReplays.tsx
index 7d385133410829..4d00ed547ff87f 100644
--- a/static/app/components/replays/table/deleteReplays.tsx
+++ b/static/app/components/replays/table/deleteReplays.tsx
@@ -13,7 +13,7 @@ import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicato
import {useAnalyticsArea} from 'sentry/components/analyticsArea';
import {openConfirmModal} from 'sentry/components/confirm';
import {Duration} from 'sentry/components/duration/duration';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {KeyValueData} from 'sentry/components/keyValueData';
import {useReplayBulkDeleteAuditLogQueryKey} from 'sentry/components/replays/bulkDelete/useReplayBulkDeleteAuditLog';
import {SimpleTable} from 'sentry/components/tables/simpleTable';
diff --git a/static/app/components/replays/usePlaylistQuery.tsx b/static/app/components/replays/usePlaylistQuery.tsx
index 1ab31798a5c3eb..77c45e1f02861b 100644
--- a/static/app/components/replays/usePlaylistQuery.tsx
+++ b/static/app/components/replays/usePlaylistQuery.tsx
@@ -1,7 +1,7 @@
import type {Query} from 'history';
import {parseStatsPeriod} from 'sentry/components/timeRangeSelector/utils';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {useLocation} from 'sentry/utils/useLocation';
import type {ReplayListQueryReferrer} from 'sentry/views/replays/types';
diff --git a/static/app/components/search/index.tsx b/static/app/components/search/index.tsx
index 0a0f19b5f27537..09aad3eee1b9d7 100644
--- a/static/app/components/search/index.tsx
+++ b/static/app/components/search/index.tsx
@@ -4,7 +4,7 @@ import debounce from 'lodash/debounce';
import {addErrorMessage} from 'sentry/actionCreators/indicator';
import {navigateTo} from 'sentry/actionCreators/navigation';
-import AutoComplete from 'sentry/components/autoComplete';
+import {AutoComplete} from 'sentry/components/autoComplete';
import {t} from 'sentry/locale';
import {trackAnalytics} from 'sentry/utils/analytics';
import type {Fuse} from 'sentry/utils/fuzzySearch';
diff --git a/static/app/components/search/list.tsx b/static/app/components/search/list.tsx
index 3c28812c815fde..cbb47f58a2d35f 100644
--- a/static/app/components/search/list.tsx
+++ b/static/app/components/search/list.tsx
@@ -3,7 +3,7 @@ import styled from '@emotion/styled';
import {Flex} from '@sentry/scraps/layout';
-import type AutoComplete from 'sentry/components/autoComplete';
+import type {AutoComplete} from 'sentry/components/autoComplete';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {t} from 'sentry/locale';
diff --git a/static/app/components/stream/group.tsx b/static/app/components/stream/group.tsx
index 6eedd13afc703f..beda07ed787d5e 100644
--- a/static/app/components/stream/group.tsx
+++ b/static/app/components/stream/group.tsx
@@ -38,7 +38,7 @@ import type {NewQuery} from 'sentry/types/organization';
import type {User} from 'sentry/types/user';
import {defined, percent} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {SavedQueryDatasets} from 'sentry/utils/discover/types';
import {isCtrlKeyPressed} from 'sentry/utils/isCtrlKeyPressed';
import {getConfigForIssueType} from 'sentry/utils/issueTypeConfig';
diff --git a/static/app/data/languages.tsx b/static/app/data/languages.tsx
index f7cb1b094141c8..739032e8093a77 100644
--- a/static/app/data/languages.tsx
+++ b/static/app/data/languages.tsx
@@ -1,4 +1,4 @@
-export default [
+export const languages = [
['ja', 'Japanese'],
['it', 'Italian'],
['zh-tw', 'Traditional Chinese'],
diff --git a/static/app/plugins/basePlugin.tsx b/static/app/plugins/basePlugin.tsx
index 264fb4ce622f72..cb7ebfe9627f1b 100644
--- a/static/app/plugins/basePlugin.tsx
+++ b/static/app/plugins/basePlugin.tsx
@@ -1,4 +1,4 @@
-import Settings from 'sentry/plugins/components/settings';
+import {PluginSettings} from 'sentry/plugins/components/settings';
import type {Plugin} from 'sentry/types/integrations';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
@@ -8,15 +8,13 @@ type Props = {
project: Project;
};
-class BasePlugin {
+export class BasePlugin {
plugin: Plugin;
constructor(data: Plugin) {
this.plugin = data;
}
renderSettings(props: Props) {
- return ;
+ return ;
}
}
-
-export default BasePlugin;
diff --git a/static/app/plugins/components/issueActions.tsx b/static/app/plugins/components/issueActions.tsx
index 5ec769e4bd7666..8fe70355652437 100644
--- a/static/app/plugins/components/issueActions.tsx
+++ b/static/app/plugins/components/issueActions.tsx
@@ -3,12 +3,12 @@ import {Fragment} from 'react';
import {Alert} from '@sentry/scraps/alert';
import {Button, LinkButton} from '@sentry/scraps/button';
-import Form from 'sentry/components/deprecatedforms/form';
-import FormState from 'sentry/components/forms/state';
+import {Form} from 'sentry/components/deprecatedforms/form';
+import {FormState} from 'sentry/components/forms/state';
import {LoadingError} from 'sentry/components/loadingError';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {t} from 'sentry/locale';
-import PluginComponentBase from 'sentry/plugins/pluginComponentBase';
+import {PluginComponentBase} from 'sentry/plugins/pluginComponentBase';
import {GroupStore} from 'sentry/stores/groupStore';
import type {Group} from 'sentry/types/group';
import type {Plugin} from 'sentry/types/integrations';
@@ -60,7 +60,7 @@ type State = {
unlinkFieldList?: Field[];
} & PluginComponentBase['state'];
-class IssueActions extends PluginComponentBase {
+export class IssueActions extends PluginComponentBase {
constructor(props: Props) {
super(props);
@@ -572,5 +572,3 @@ class IssueActions extends PluginComponentBase {
);
}
}
-
-export default IssueActions;
diff --git a/static/app/plugins/components/settings.tsx b/static/app/plugins/components/settings.tsx
index 4572b159abb45e..1262524bcef46d 100644
--- a/static/app/plugins/components/settings.tsx
+++ b/static/app/plugins/components/settings.tsx
@@ -5,11 +5,11 @@ import {Alert} from '@sentry/scraps/alert';
import {LinkButton} from '@sentry/scraps/button';
import {Stack} from '@sentry/scraps/layout';
-import Form from 'sentry/components/deprecatedforms/form';
-import FormState from 'sentry/components/forms/state';
+import {Form} from 'sentry/components/deprecatedforms/form';
+import {FormState} from 'sentry/components/forms/state';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {t, tct} from 'sentry/locale';
-import PluginComponentBase from 'sentry/plugins/pluginComponentBase';
+import {PluginComponentBase} from 'sentry/plugins/pluginComponentBase';
import type {Plugin} from 'sentry/types/integrations';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
@@ -36,7 +36,7 @@ type State = {
wasConfiguredOnPageLoad: boolean;
} & PluginComponentBase['state'];
-class PluginSettings<
+export class PluginSettings<
P extends Props = Props,
S extends State = State,
> extends PluginComponentBase {
@@ -246,5 +246,3 @@ class PluginSettings<
);
}
}
-
-export default PluginSettings;
diff --git a/static/app/plugins/defaultIssuePlugin.tsx b/static/app/plugins/defaultIssuePlugin.tsx
index a92c461a95bc25..a38fbcbf6aff1f 100644
--- a/static/app/plugins/defaultIssuePlugin.tsx
+++ b/static/app/plugins/defaultIssuePlugin.tsx
@@ -1,5 +1,5 @@
-import BasePlugin from 'sentry/plugins/basePlugin';
-import IssueActions from 'sentry/plugins/components/issueActions';
+import {BasePlugin} from 'sentry/plugins/basePlugin';
+import {IssueActions} from 'sentry/plugins/components/issueActions';
import type {Group} from 'sentry/types/group';
import type {Plugin} from 'sentry/types/integrations';
import type {Organization} from 'sentry/types/organization';
diff --git a/static/app/plugins/defaultPlugin.tsx b/static/app/plugins/defaultPlugin.tsx
index f5d17f6d5e03ca..679eea75b9c568 100644
--- a/static/app/plugins/defaultPlugin.tsx
+++ b/static/app/plugins/defaultPlugin.tsx
@@ -1,4 +1,4 @@
-import BasePlugin from 'sentry/plugins/basePlugin';
+import {BasePlugin} from 'sentry/plugins/basePlugin';
class DefaultPlugin extends BasePlugin {
static displayName = 'DefaultPlugin';
diff --git a/static/app/plugins/index.tsx b/static/app/plugins/index.tsx
index f0b37c9d0cd767..1b828323821fc5 100644
--- a/static/app/plugins/index.tsx
+++ b/static/app/plugins/index.tsx
@@ -1,4 +1,4 @@
-import BasePlugin from 'sentry/plugins/basePlugin';
+import {BasePlugin} from 'sentry/plugins/basePlugin';
import {DefaultIssuePlugin} from 'sentry/plugins/defaultIssuePlugin';
import {Registry} from 'sentry/plugins/registry';
diff --git a/static/app/plugins/jira/components/issueActions.tsx b/static/app/plugins/jira/components/issueActions.tsx
index 19d0dd09f8752a..1f35bc5940fb95 100644
--- a/static/app/plugins/jira/components/issueActions.tsx
+++ b/static/app/plugins/jira/components/issueActions.tsx
@@ -1,9 +1,9 @@
-import Form from 'sentry/components/deprecatedforms/form';
-import FormState from 'sentry/components/forms/state';
-import DefaultIssueActions from 'sentry/plugins/components/issueActions';
+import {Form} from 'sentry/components/deprecatedforms/form';
+import {FormState} from 'sentry/components/forms/state';
+import {IssueActions as DefaultIssueActions} from 'sentry/plugins/components/issueActions';
import type {Writable} from 'sentry/types/core';
-class IssueActions extends DefaultIssueActions {
+export class IssueActions extends DefaultIssueActions {
changeField = (
action: DefaultIssueActions['props']['actionType'],
name: string,
@@ -116,5 +116,3 @@ class IssueActions extends DefaultIssueActions {
return form;
}
}
-
-export default IssueActions;
diff --git a/static/app/plugins/jira/components/settings.tsx b/static/app/plugins/jira/components/settings.tsx
index d758b46696f2a6..c3a56d9e392c71 100644
--- a/static/app/plugins/jira/components/settings.tsx
+++ b/static/app/plugins/jira/components/settings.tsx
@@ -4,11 +4,11 @@ import isEqual from 'lodash/isEqual';
import {Alert} from '@sentry/scraps/alert';
import {Button} from '@sentry/scraps/button';
-import Form from 'sentry/components/deprecatedforms/form';
-import FormState from 'sentry/components/forms/state';
+import {Form} from 'sentry/components/deprecatedforms/form';
+import {FormState} from 'sentry/components/forms/state';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {t} from 'sentry/locale';
-import DefaultSettings from 'sentry/plugins/components/settings';
+import {PluginSettings as DefaultSettings} from 'sentry/plugins/components/settings';
type Field = Parameters[0]['config'];
@@ -29,7 +29,7 @@ const PAGE_FIELD_LIST = {
2: ['ignored_fields', 'default_priority', 'default_issue_type', 'auto_create'],
};
-class Settings extends DefaultSettings {
+export class Settings extends DefaultSettings {
constructor(props: Props) {
super(props);
@@ -211,5 +211,3 @@ class Settings extends DefaultSettings {
const FloatLeftButton = styled(Button)`
float: left;
`;
-
-export default Settings;
diff --git a/static/app/plugins/jira/index.tsx b/static/app/plugins/jira/index.tsx
index 1826da55fb3012..608f1d6d1576ca 100644
--- a/static/app/plugins/jira/index.tsx
+++ b/static/app/plugins/jira/index.tsx
@@ -1,8 +1,8 @@
-import type BasePlugin from 'sentry/plugins/basePlugin';
+import type {BasePlugin} from 'sentry/plugins/basePlugin';
import {DefaultIssuePlugin} from 'sentry/plugins/defaultIssuePlugin';
-import IssueActions from './components/issueActions';
-import Settings from './components/settings';
+import {IssueActions} from './components/issueActions';
+import {Settings} from './components/settings';
export class Jira extends DefaultIssuePlugin {
displayName = 'Jira';
diff --git a/static/app/plugins/pluginComponentBase.tsx b/static/app/plugins/pluginComponentBase.tsx
index c1dbf51ded96cb..abd254eee5711e 100644
--- a/static/app/plugins/pluginComponentBase.tsx
+++ b/static/app/plugins/pluginComponentBase.tsx
@@ -9,7 +9,7 @@ import {
} from 'sentry/actionCreators/indicator';
import {Client} from 'sentry/api';
import {GenericField} from 'sentry/components/deprecatedforms/genericField';
-import FormState from 'sentry/components/forms/state';
+import {FormState} from 'sentry/components/forms/state';
import {t} from 'sentry/locale';
const callbackWithArgs = function (context: any, callback: any, ...args: any) {
@@ -22,7 +22,7 @@ type Props = Record;
type State = {state: FormState};
-abstract class PluginComponentBase<
+export abstract class PluginComponentBase<
P extends Props = Props,
S extends State = State,
> extends Component {
@@ -156,5 +156,3 @@ abstract class PluginComponentBase<
return ;
}
}
-
-export default PluginComponentBase;
diff --git a/static/app/plugins/sessionstack/components/settings.tsx b/static/app/plugins/sessionstack/components/settings.tsx
index c05d5579b36875..50e5df580dfe7a 100644
--- a/static/app/plugins/sessionstack/components/settings.tsx
+++ b/static/app/plugins/sessionstack/components/settings.tsx
@@ -3,11 +3,11 @@ import isEqual from 'lodash/isEqual';
import {Alert} from '@sentry/scraps/alert';
import {Button} from '@sentry/scraps/button';
-import Form from 'sentry/components/deprecatedforms/form';
-import FormState from 'sentry/components/forms/state';
+import {Form} from 'sentry/components/deprecatedforms/form';
+import {FormState} from 'sentry/components/forms/state';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {t} from 'sentry/locale';
-import DefaultSettings from 'sentry/plugins/components/settings';
+import {PluginSettings as DefaultSettings} from 'sentry/plugins/components/settings';
type Props = DefaultSettings['props'];
@@ -19,7 +19,7 @@ type State = DefaultSettings['state'] & {
showOnPremisesConfiguration?: boolean;
};
-class Settings extends DefaultSettings {
+export class Settings extends DefaultSettings {
REQUIRED_FIELDS = ['account_email', 'api_token', 'website_id'];
ON_PREMISES_FIELDS = ['api_url', 'player_url'];
@@ -93,5 +93,3 @@ class Settings extends DefaultSettings {
);
}
}
-
-export default Settings;
diff --git a/static/app/plugins/sessionstack/index.tsx b/static/app/plugins/sessionstack/index.tsx
index 7e45706d63944d..d673e613d3e6f3 100644
--- a/static/app/plugins/sessionstack/index.tsx
+++ b/static/app/plugins/sessionstack/index.tsx
@@ -1,6 +1,6 @@
-import BasePlugin from 'sentry/plugins/basePlugin';
+import {BasePlugin} from 'sentry/plugins/basePlugin';
-import Settings from './components/settings';
+import {Settings} from './components/settings';
export class SessionStackPlugin extends BasePlugin {
displayName = 'SessionStack';
diff --git a/static/app/router/routes.tsx b/static/app/router/routes.tsx
index 334eec6063593e..0d617cc100f316 100644
--- a/static/app/router/routes.tsx
+++ b/static/app/router/routes.tsx
@@ -37,7 +37,7 @@ import {IssueTaxonomy} from 'sentry/views/issueList/taxonomies';
import {OrganizationContainerRoute} from 'sentry/views/organizationContainer';
import {OrganizationLayout} from 'sentry/views/organizationLayout';
import {OrganizationStatsWrapper} from 'sentry/views/organizationStats/organizationStatsWrapper';
-import TransactionSummaryTab from 'sentry/views/performance/transactionSummary/tabs';
+import {Tab as TransactionSummaryTab} from 'sentry/views/performance/transactionSummary/tabs';
import {ProjectEventRedirect} from 'sentry/views/projectEventRedirect';
import {redirectDeprecatedProjectRoute} from 'sentry/views/projects/redirectDeprecatedProjectRoute';
import {RouteNotFound} from 'sentry/views/routeNotFound';
diff --git a/static/app/utils/cursorPoller.tsx b/static/app/utils/cursorPoller.tsx
index 911461657ccb09..98289cfd3c5668 100644
--- a/static/app/utils/cursorPoller.tsx
+++ b/static/app/utils/cursorPoller.tsx
@@ -11,7 +11,7 @@ type Options = {
const BASE_DELAY = 3000;
const MAX_DELAY = 60000;
-class CursorPoller {
+export class CursorPoller {
constructor(options: Options) {
this.options = options;
this.setEndpoint(options.linkPreviousHref);
@@ -117,5 +117,3 @@ class CursorPoller {
});
}
}
-
-export default CursorPoller;
diff --git a/static/app/utils/dashboards/issueFieldRenderers.tsx b/static/app/utils/dashboards/issueFieldRenderers.tsx
index 4e4b1e45c612cd..e6143e3fbc7524 100644
--- a/static/app/utils/dashboards/issueFieldRenderers.tsx
+++ b/static/app/utils/dashboards/issueFieldRenderers.tsx
@@ -13,7 +13,7 @@ import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import {IssueAssignee} from 'sentry/utils/dashboards/issueAssignee';
import type {EventData, MetaType} from 'sentry/utils/discover/eventView';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import type {FieldFormatterRenderFunctionPartial} from 'sentry/utils/discover/fieldRenderers';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import {Container, FieldShortId, OverflowLink} from 'sentry/utils/discover/styles';
diff --git a/static/app/utils/discover/discoverQuery.spec.tsx b/static/app/utils/discover/discoverQuery.spec.tsx
index e90d13274448ed..f476177d559ca1 100644
--- a/static/app/utils/discover/discoverQuery.spec.tsx
+++ b/static/app/utils/discover/discoverQuery.spec.tsx
@@ -1,7 +1,7 @@
import {render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
import {DiscoverQuery} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
describe('DiscoverQuery', () => {
let location: any, eventView: any;
diff --git a/static/app/utils/discover/eventView.spec.tsx b/static/app/utils/discover/eventView.spec.tsx
index df0f1d395f85ba..0a985d6119d3f0 100644
--- a/static/app/utils/discover/eventView.spec.tsx
+++ b/static/app/utils/discover/eventView.spec.tsx
@@ -8,7 +8,8 @@ import {ConfigStore} from 'sentry/stores/configStore';
import type {NewQuery, SavedQuery} from 'sentry/types/organization';
import type {Config} from 'sentry/types/system';
import type {MetaType} from 'sentry/utils/discover/eventView';
-import EventView, {
+import {
+ EventView,
isAPIPayloadSimilar,
pickRelevantLocationQueryStrings,
} from 'sentry/utils/discover/eventView';
diff --git a/static/app/utils/discover/eventView.tsx b/static/app/utils/discover/eventView.tsx
index 7376d518d52747..d7855bfc166070 100644
--- a/static/app/utils/discover/eventView.tsx
+++ b/static/app/utils/discover/eventView.tsx
@@ -294,7 +294,7 @@ export type EventViewOptions = {
yAxis?: string | string[] | undefined;
};
-class EventView {
+export class EventView {
id: string | undefined;
name: string | undefined;
fields: readonly Field[];
@@ -1581,5 +1581,3 @@ export function pickRelevantLocationQueryStrings(location: Location) {
return picked;
}
-
-export default EventView;
diff --git a/static/app/utils/discover/fieldRenderers.spec.tsx b/static/app/utils/discover/fieldRenderers.spec.tsx
index 784cf4c006aeec..ab1f7b057aeddf 100644
--- a/static/app/utils/discover/fieldRenderers.spec.tsx
+++ b/static/app/utils/discover/fieldRenderers.spec.tsx
@@ -7,7 +7,7 @@ import {initializeOrg} from 'sentry-test/initializeOrg';
import {act, render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
import {ProjectsStore} from 'sentry/stores/projectsStore';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import {SPAN_OP_RELATIVE_BREAKDOWN_FIELD} from 'sentry/utils/discover/fields';
import {WidgetType, type DashboardFilters} from 'sentry/views/dashboards/types';
diff --git a/static/app/utils/discover/fieldRenderers.tsx b/static/app/utils/discover/fieldRenderers.tsx
index e45f9b9176e7da..dbc36c95700fc4 100644
--- a/static/app/utils/discover/fieldRenderers.tsx
+++ b/static/app/utils/discover/fieldRenderers.tsx
@@ -32,8 +32,7 @@ import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
import {toArray} from 'sentry/utils/array/toArray';
import {browserHistory} from 'sentry/utils/browserHistory';
-import type EventView from 'sentry/utils/discover/eventView';
-import type {EventData, MetaType} from 'sentry/utils/discover/eventView';
+import type {EventData, EventView, MetaType} from 'sentry/utils/discover/eventView';
import type {RateUnit} from 'sentry/utils/discover/fields';
import {
ABYTE_UNITS,
diff --git a/static/app/utils/discover/genericDiscoverQuery.tsx b/static/app/utils/discover/genericDiscoverQuery.tsx
index d04dd5796c9254..f621325d8ecced 100644
--- a/static/app/utils/discover/genericDiscoverQuery.tsx
+++ b/static/app/utils/discover/genericDiscoverQuery.tsx
@@ -6,8 +6,11 @@ import type {EventQuery} from 'sentry/actionCreators/events';
import type {ResponseMeta} from 'sentry/api';
import {Client} from 'sentry/api';
import {t} from 'sentry/locale';
-import type EventView from 'sentry/utils/discover/eventView';
-import type {ImmutableEventView, LocationQuery} from 'sentry/utils/discover/eventView';
+import type {
+ EventView,
+ ImmutableEventView,
+ LocationQuery,
+} from 'sentry/utils/discover/eventView';
import {isAPIPayloadSimilar} from 'sentry/utils/discover/eventView';
import {PerformanceEventViewContext} from 'sentry/utils/performance/contexts/performanceEventViewContext';
import type {UseQueryOptions} from 'sentry/utils/queryClient';
diff --git a/static/app/utils/discover/urls.tsx b/static/app/utils/discover/urls.tsx
index 21dc6975425f08..6ae69b04acb2c3 100644
--- a/static/app/utils/discover/urls.tsx
+++ b/static/app/utils/discover/urls.tsx
@@ -10,7 +10,7 @@ import type {TraceLayoutTabKeys} from 'sentry/views/performance/newTraceDetails/
import {getTraceDetailsUrl} from 'sentry/views/performance/traceDetails/utils';
import type {EventData} from './eventView';
-import EventView from './eventView';
+import {EventView} from './eventView';
/**
* Create a slug that can be used with discover details views
diff --git a/static/app/utils/performance/contexts/metricsCardinality.tsx b/static/app/utils/performance/contexts/metricsCardinality.tsx
index 73599395bce7e5..462a67cb67abfd 100644
--- a/static/app/utils/performance/contexts/metricsCardinality.tsx
+++ b/static/app/utils/performance/contexts/metricsCardinality.tsx
@@ -4,7 +4,7 @@ import type {Location} from 'history';
import type {Organization} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {parsePeriodToHours} from 'sentry/utils/duration/parsePeriodToHours';
import {canUseMetricsData} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
diff --git a/static/app/utils/performance/contexts/performanceEventViewContext.tsx b/static/app/utils/performance/contexts/performanceEventViewContext.tsx
index 035fde381a48b6..7e1e31ad83d769 100644
--- a/static/app/utils/performance/contexts/performanceEventViewContext.tsx
+++ b/static/app/utils/performance/contexts/performanceEventViewContext.tsx
@@ -1,4 +1,4 @@
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {createDefinedContext} from './utils';
diff --git a/static/app/utils/performance/histogram/histogramQuery.spec.tsx b/static/app/utils/performance/histogram/histogramQuery.spec.tsx
index c2acb4a0970b70..ed90b64e6aea7c 100644
--- a/static/app/utils/performance/histogram/histogramQuery.spec.tsx
+++ b/static/app/utils/performance/histogram/histogramQuery.spec.tsx
@@ -2,7 +2,7 @@ import {Fragment} from 'react';
import {render, screen} from 'sentry-test/reactTestingLibrary';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {HistogramQuery} from 'sentry/utils/performance/histogram/histogramQuery';
function renderHistogram({isLoading, error, histograms}: any) {
diff --git a/static/app/utils/performance/metricsEnhanced/metricsCompatibilityQuery.tsx b/static/app/utils/performance/metricsEnhanced/metricsCompatibilityQuery.tsx
index 5922dbc5fa46d9..cab2cc054bbd14 100644
--- a/static/app/utils/performance/metricsEnhanced/metricsCompatibilityQuery.tsx
+++ b/static/app/utils/performance/metricsEnhanced/metricsCompatibilityQuery.tsx
@@ -1,6 +1,6 @@
import omit from 'lodash/omit';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {
DiscoverQueryProps,
GenericChildrenProps,
diff --git a/static/app/utils/performance/metricsEnhanced/metricsCompatibilityQuerySums.tsx b/static/app/utils/performance/metricsEnhanced/metricsCompatibilityQuerySums.tsx
index a307684ef37e7f..3916d26af6c665 100644
--- a/static/app/utils/performance/metricsEnhanced/metricsCompatibilityQuerySums.tsx
+++ b/static/app/utils/performance/metricsEnhanced/metricsCompatibilityQuerySums.tsx
@@ -1,6 +1,6 @@
import omit from 'lodash/omit';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {
DiscoverQueryProps,
GenericChildrenProps,
diff --git a/static/app/utils/replays/fetchReplayList.tsx b/static/app/utils/replays/fetchReplayList.tsx
index 338d48ded3a2f7..0a4aba9cb3ac09 100644
--- a/static/app/utils/replays/fetchReplayList.tsx
+++ b/static/app/utils/replays/fetchReplayList.tsx
@@ -5,7 +5,7 @@ import type {Client} from 'sentry/api';
import {ALL_ACCESS_PROJECTS} from 'sentry/components/pageFilters/constants';
import type {PageFilters} from 'sentry/types/core';
import type {Organization} from 'sentry/types/organization';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {mapResponseToReplayRecord} from 'sentry/utils/replays/replayDataUtils';
import type {RequestError} from 'sentry/utils/requestError/requestError';
import type {ReplayListQueryReferrer, ReplayListRecord} from 'sentry/views/replays/types';
diff --git a/static/app/utils/replays/hooks/useReplayList.tsx b/static/app/utils/replays/hooks/useReplayList.tsx
index c4924cb72fcf6b..20844a6ebd0c6b 100644
--- a/static/app/utils/replays/hooks/useReplayList.tsx
+++ b/static/app/utils/replays/hooks/useReplayList.tsx
@@ -3,7 +3,7 @@ import type {Location} from 'history';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import type {Organization} from 'sentry/types/organization';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {fetchReplayList} from 'sentry/utils/replays/fetchReplayList';
import {useApi} from 'sentry/utils/useApi';
import type {
diff --git a/static/app/views/alerts/create.tsx b/static/app/views/alerts/create.tsx
index 7ba1d7fe4efe8d..8230782cf304cf 100644
--- a/static/app/views/alerts/create.tsx
+++ b/static/app/views/alerts/create.tsx
@@ -5,7 +5,7 @@ import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {SentryDocumentTitle} from 'sentry/components/sentryDocumentTitle';
import {t} from 'sentry/locale';
import {trackAnalytics} from 'sentry/utils/analytics';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {uniqueId} from 'sentry/utils/guid';
import {decodeScalar} from 'sentry/utils/queryString';
import {useRouteAnalyticsEventNames} from 'sentry/utils/routeAnalytics/useRouteAnalyticsEventNames';
diff --git a/static/app/views/alerts/list/incidents/index.tsx b/static/app/views/alerts/list/incidents/index.tsx
index fbd6a6b0af8522..b3d75f8a7cf9ca 100644
--- a/static/app/views/alerts/list/incidents/index.tsx
+++ b/static/app/views/alerts/list/incidents/index.tsx
@@ -9,7 +9,7 @@ import {ExternalLink} from '@sentry/scraps/link';
import {promptsCheck, promptsUpdate} from 'sentry/actionCreators/prompts';
import Feature from 'sentry/components/acl/feature';
import {CreateAlertButton} from 'sentry/components/createAlertButton';
-import DeprecatedAsyncComponent from 'sentry/components/deprecatedAsyncComponent';
+import {DeprecatedAsyncComponent} from 'sentry/components/deprecatedAsyncComponent';
import * as Layout from 'sentry/components/layouts/thirds';
import {PageFiltersContainer} from 'sentry/components/pageFilters/container';
import {Pagination} from 'sentry/components/pagination';
diff --git a/static/app/views/alerts/list/incidents/row.tsx b/static/app/views/alerts/list/incidents/row.tsx
index db4bd4968aad76..352c1ac1390d1b 100644
--- a/static/app/views/alerts/list/incidents/row.tsx
+++ b/static/app/views/alerts/list/incidents/row.tsx
@@ -7,7 +7,7 @@ import {Tag} from '@sentry/scraps/badge';
import {Link} from '@sentry/scraps/link';
import {Duration} from 'sentry/components/duration';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {IdBadge} from 'sentry/components/idBadge';
import {TimeSince} from 'sentry/components/timeSince';
import {t} from 'sentry/locale';
diff --git a/static/app/views/alerts/list/rules/row.tsx b/static/app/views/alerts/list/rules/row.tsx
index e3f7df49782a33..89278ddf473f0d 100644
--- a/static/app/views/alerts/list/rules/row.tsx
+++ b/static/app/views/alerts/list/rules/row.tsx
@@ -13,7 +13,7 @@ import {Access} from 'sentry/components/acl/access';
import {openConfirmModal} from 'sentry/components/confirm';
import type {MenuItemProps} from 'sentry/components/dropdownMenu';
import {DropdownMenu} from 'sentry/components/dropdownMenu';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {IdBadge} from 'sentry/components/idBadge';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {TextOverflow} from 'sentry/components/textOverflow';
diff --git a/static/app/views/alerts/rules/issue/details/ruleDetails.tsx b/static/app/views/alerts/rules/issue/details/ruleDetails.tsx
index ab3e46ee4d4441..1e202c80134802 100644
--- a/static/app/views/alerts/rules/issue/details/ruleDetails.tsx
+++ b/static/app/views/alerts/rules/issue/details/ruleDetails.tsx
@@ -12,7 +12,7 @@ import {Access} from 'sentry/components/acl/access';
import {SnoozeAlert} from 'sentry/components/alerts/snoozeAlert';
import {Breadcrumbs} from 'sentry/components/breadcrumbs';
import type {DateTimeObject} from 'sentry/components/charts/utils';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {IdBadge} from 'sentry/components/idBadge';
import * as Layout from 'sentry/components/layouts/thirds';
import {LoadingError} from 'sentry/components/loadingError';
diff --git a/static/app/views/alerts/rules/issue/index.tsx b/static/app/views/alerts/rules/issue/index.tsx
index e86d7a1da70556..cd63e0aea725a4 100644
--- a/static/app/views/alerts/rules/issue/index.tsx
+++ b/static/app/views/alerts/rules/issue/index.tsx
@@ -23,8 +23,8 @@ import {
} from 'sentry/actionCreators/indicator';
import {hasEveryAccess} from 'sentry/components/acl/access';
import {Confirm} from 'sentry/components/confirm';
-import DeprecatedAsyncComponent from 'sentry/components/deprecatedAsyncComponent';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {DeprecatedAsyncComponent} from 'sentry/components/deprecatedAsyncComponent';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {components} from 'sentry/components/forms/controls/reactSelectWrapper';
import {FieldGroup} from 'sentry/components/forms/fieldGroup';
import {FieldHelp} from 'sentry/components/forms/fieldGroup/fieldHelp';
@@ -80,7 +80,7 @@ import {
} from 'sentry/views/alerts/utils/constants';
import {ProjectPermissionAlert} from 'sentry/views/settings/project/projectPermissionAlert';
-import RuleNodeList from './ruleNodeList';
+import {RuleNodeList} from './ruleNodeList';
const FREQUENCY_OPTIONS = [
{value: '5', label: t('5 minutes')},
diff --git a/static/app/views/alerts/rules/issue/memberTeamFields.tsx b/static/app/views/alerts/rules/issue/memberTeamFields.tsx
index 368f9210ca3f12..5eadf4b5094bba 100644
--- a/static/app/views/alerts/rules/issue/memberTeamFields.tsx
+++ b/static/app/views/alerts/rules/issue/memberTeamFields.tsx
@@ -27,7 +27,7 @@ type Props = {
teamValue: string | number;
};
-class MemberTeamFields extends Component {
+export class MemberTeamFields extends Component {
handleChange = (attribute: 'targetType' | 'targetIdentifier', newValue: string) => {
const {onChange, ruleData} = this.props;
if (newValue === ruleData[attribute]) {
@@ -131,5 +131,3 @@ const PanelItemGrid = styled(PanelItem)`
const SelectWrapper = styled('div')`
width: 200px;
`;
-
-export default MemberTeamFields;
diff --git a/static/app/views/alerts/rules/issue/ruleNode.tsx b/static/app/views/alerts/rules/issue/ruleNode.tsx
index 63c3bc5e29d7de..fcafbd0f5a158a 100644
--- a/static/app/views/alerts/rules/issue/ruleNode.tsx
+++ b/static/app/views/alerts/rules/issue/ruleNode.tsx
@@ -32,7 +32,7 @@ import type {IssueCategory} from 'sentry/types/group';
import {VALID_ISSUE_CATEGORIES} from 'sentry/types/group';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
-import MemberTeamFields from 'sentry/views/alerts/rules/issue/memberTeamFields';
+import {MemberTeamFields} from 'sentry/views/alerts/rules/issue/memberTeamFields';
import {SentryAppRuleModal} from 'sentry/views/alerts/rules/issue/sentryAppRuleModal';
interface FieldProps {
diff --git a/static/app/views/alerts/rules/issue/ruleNodeList.tsx b/static/app/views/alerts/rules/issue/ruleNodeList.tsx
index 4dd1ea914570b9..c30a7813fa6889 100644
--- a/static/app/views/alerts/rules/issue/ruleNodeList.tsx
+++ b/static/app/views/alerts/rules/issue/ruleNodeList.tsx
@@ -135,7 +135,7 @@ const groupSelectOptions = (actions: IssueAlertRuleActionTemplate[]) => {
});
};
-class RuleNodeList extends Component {
+export class RuleNodeList extends Component {
componentWillUnmount() {
window.clearTimeout(this.propertyChangeTimeout);
}
@@ -308,8 +308,6 @@ class RuleNodeList extends Component {
}
}
-export default RuleNodeList;
-
const StyledSelectControl = styled(Select)`
width: 100%;
`;
diff --git a/static/app/views/alerts/rules/metric/constants.spec.tsx b/static/app/views/alerts/rules/metric/constants.spec.tsx
index 1bec8e6b819a4f..61b62621e155f6 100644
--- a/static/app/views/alerts/rules/metric/constants.spec.tsx
+++ b/static/app/views/alerts/rules/metric/constants.spec.tsx
@@ -1,7 +1,7 @@
import {UserFixture} from 'sentry-fixture/user';
import type {EventViewOptions} from 'sentry/utils/discover/eventView';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {createRuleFromEventView} from 'sentry/views/alerts/rules/metric/constants';
import {Dataset, EventTypes} from 'sentry/views/alerts/rules/metric/types';
diff --git a/static/app/views/alerts/rules/metric/constants.tsx b/static/app/views/alerts/rules/metric/constants.tsx
index 5ed365d50789b2..8dfdd49efdd9c2 100644
--- a/static/app/views/alerts/rules/metric/constants.tsx
+++ b/static/app/views/alerts/rules/metric/constants.tsx
@@ -1,7 +1,7 @@
import pick from 'lodash/pick';
import {t, tct} from 'sentry/locale';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {AggregationKeyWithAlias, LooseFieldKey} from 'sentry/utils/discover/fields';
import {parseFunction, SPAN_OP_BREAKDOWN_FIELDS} from 'sentry/utils/discover/fields';
import {parsePeriodToHours} from 'sentry/utils/duration/parsePeriodToHours';
diff --git a/static/app/views/alerts/rules/metric/create.spec.tsx b/static/app/views/alerts/rules/metric/create.spec.tsx
index b7b821d6f0c593..6282608588b2ea 100644
--- a/static/app/views/alerts/rules/metric/create.spec.tsx
+++ b/static/app/views/alerts/rules/metric/create.spec.tsx
@@ -5,7 +5,7 @@ import {RouteComponentPropsFixture} from 'sentry-fixture/routeComponentPropsFixt
import {initializeOrg} from 'sentry-test/initializeOrg';
import {render, waitFor} from 'sentry-test/reactTestingLibrary';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MetricRulesCreate} from 'sentry/views/alerts/rules/metric/create';
describe('Incident Rules Create', () => {
diff --git a/static/app/views/alerts/rules/metric/create.tsx b/static/app/views/alerts/rules/metric/create.tsx
index 088bd8add5c414..4e83dce41f2e7d 100644
--- a/static/app/views/alerts/rules/metric/create.tsx
+++ b/static/app/views/alerts/rules/metric/create.tsx
@@ -4,7 +4,7 @@ import type {RouteComponentProps} from 'sentry/types/legacyReactRouter';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {metric} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {decodeScalar} from 'sentry/utils/queryString';
import {normalizeUrl} from 'sentry/utils/url/normalizeUrl';
import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
diff --git a/static/app/views/alerts/rules/metric/duplicate.tsx b/static/app/views/alerts/rules/metric/duplicate.tsx
index 8fc815e75865dd..3ee24466d24ae8 100644
--- a/static/app/views/alerts/rules/metric/duplicate.tsx
+++ b/static/app/views/alerts/rules/metric/duplicate.tsx
@@ -6,7 +6,7 @@ import {LoadingError} from 'sentry/components/loadingError';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import type {RouteComponentProps} from 'sentry/types/legacyReactRouter';
import type {Project} from 'sentry/types/project';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {uniqueId} from 'sentry/utils/guid';
import {normalizeUrl} from 'sentry/utils/url/normalizeUrl';
import {useOrganization} from 'sentry/utils/useOrganization';
diff --git a/static/app/views/alerts/rules/metric/incompatibleAlertQuery.spec.tsx b/static/app/views/alerts/rules/metric/incompatibleAlertQuery.spec.tsx
index 921dfd0e6e9bbe..9ad5a1ea30f279 100644
--- a/static/app/views/alerts/rules/metric/incompatibleAlertQuery.spec.tsx
+++ b/static/app/views/alerts/rules/metric/incompatibleAlertQuery.spec.tsx
@@ -2,7 +2,7 @@ import {OrganizationFixture} from 'sentry-fixture/organization';
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {IncompatibleAlertQuery} from 'sentry/views/alerts/rules/metric/incompatibleAlertQuery';
import {DEFAULT_EVENT_VIEW, getAllViews} from 'sentry/views/discover/results/data';
diff --git a/static/app/views/alerts/rules/metric/incompatibleAlertQuery.tsx b/static/app/views/alerts/rules/metric/incompatibleAlertQuery.tsx
index 809bcaec0aa7a9..d10ee144ca1be0 100644
--- a/static/app/views/alerts/rules/metric/incompatibleAlertQuery.tsx
+++ b/static/app/views/alerts/rules/metric/incompatibleAlertQuery.tsx
@@ -6,7 +6,7 @@ import {Button} from '@sentry/scraps/button';
import {IconClose} from 'sentry/icons';
import {t, tct} from 'sentry/locale';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {Aggregation} from 'sentry/utils/discover/fields';
import {AGGREGATIONS, explodeFieldString} from 'sentry/utils/discover/fields';
import {
diff --git a/static/app/views/alerts/rules/metric/ruleForm.tsx b/static/app/views/alerts/rules/metric/ruleForm.tsx
index 3be17fbbdd2c93..712860f42f9375 100644
--- a/static/app/views/alerts/rules/metric/ruleForm.tsx
+++ b/static/app/views/alerts/rules/metric/ruleForm.tsx
@@ -21,7 +21,7 @@ import {hasEveryAccess} from 'sentry/components/acl/access';
import {HeaderTitleLegend} from 'sentry/components/charts/styles';
import {CircleIndicator} from 'sentry/components/circleIndicator';
import {Confirm} from 'sentry/components/confirm';
-import DeprecatedAsyncComponent from 'sentry/components/deprecatedAsyncComponent';
+import {DeprecatedAsyncComponent} from 'sentry/components/deprecatedAsyncComponent';
import type {FormProps} from 'sentry/components/forms/form';
import {Form} from 'sentry/components/forms/form';
import {FormModel} from 'sentry/components/forms/model';
@@ -42,7 +42,7 @@ import type {
import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
import {metric, trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {parseFunction, prettifyParsedFunction} from 'sentry/utils/discover/fields';
import {AggregationKey} from 'sentry/utils/fields';
import {isOnDemandQueryString} from 'sentry/utils/onDemandMetrics';
@@ -57,7 +57,7 @@ import {IncompatibleAlertQuery} from 'sentry/views/alerts/rules/metric/incompati
import {OnDemandThresholdChecker} from 'sentry/views/alerts/rules/metric/onDemandThresholdChecker';
import {RuleNameOwnerForm} from 'sentry/views/alerts/rules/metric/ruleNameOwnerForm';
import {ThresholdTypeForm} from 'sentry/views/alerts/rules/metric/thresholdTypeForm';
-import Triggers from 'sentry/views/alerts/rules/metric/triggers';
+import {Triggers} from 'sentry/views/alerts/rules/metric/triggers';
import TriggersChart, {ErrorChart} from 'sentry/views/alerts/rules/metric/triggers/chart';
import type {SeriesSamplingInfo} from 'sentry/views/alerts/rules/metric/utils/determineSeriesSampleCount';
import {determineSeriesSampleCountAndIsSampled} from 'sentry/views/alerts/rules/metric/utils/determineSeriesSampleCount';
diff --git a/static/app/views/alerts/rules/metric/triggers/anomalyAlertsForm.tsx b/static/app/views/alerts/rules/metric/triggers/anomalyAlertsForm.tsx
index f25f54924be13b..a438c4d7ca1e6f 100644
--- a/static/app/views/alerts/rules/metric/triggers/anomalyAlertsForm.tsx
+++ b/static/app/views/alerts/rules/metric/triggers/anomalyAlertsForm.tsx
@@ -110,7 +110,7 @@ function DirectionFormItem({
);
}
-class AnomalyDetectionFormField extends Component {
+export class AnomalyDetectionFormField extends Component {
render() {
const {sensitivity, onSensitivityChange, thresholdType, onThresholdTypeChange} =
this.props;
@@ -140,4 +140,3 @@ const StyledField = styled(FieldGroup)`
const SelectContainer = styled('div')`
flex: 1;
`;
-export default AnomalyDetectionFormField;
diff --git a/static/app/views/alerts/rules/metric/triggers/chart/index.tsx b/static/app/views/alerts/rules/metric/triggers/chart/index.tsx
index aaad25192a316c..d77fd9e577e1c8 100644
--- a/static/app/views/alerts/rules/metric/triggers/chart/index.tsx
+++ b/static/app/views/alerts/rules/metric/triggers/chart/index.tsx
@@ -12,12 +12,13 @@ import {OverlayTrigger} from '@sentry/scraps/overlayTrigger';
import {fetchTotalCount} from 'sentry/actionCreators/events';
import {Client} from 'sentry/api';
import {ErrorPanel} from 'sentry/components/charts/errorPanel';
-import EventsRequest, {
+import {
+ EventsRequest,
type EventsRequestProps,
} from 'sentry/components/charts/eventsRequest';
import type {LineChartSeries} from 'sentry/components/charts/lineChart';
import {OnDemandMetricRequest} from 'sentry/components/charts/onDemandMetricRequest';
-import SessionsRequest from 'sentry/components/charts/sessionsRequest';
+import {SessionsRequest} from 'sentry/components/charts/sessionsRequest';
import {
ChartControls,
InlineContainer,
diff --git a/static/app/views/alerts/rules/metric/triggers/form.tsx b/static/app/views/alerts/rules/metric/triggers/form.tsx
index 3d80bfe3e1b3c2..d118e05098d285 100644
--- a/static/app/views/alerts/rules/metric/triggers/form.tsx
+++ b/static/app/views/alerts/rules/metric/triggers/form.tsx
@@ -14,7 +14,7 @@ import type {Config} from 'sentry/types/system';
import {withApi} from 'sentry/utils/withApi';
import {withConfig} from 'sentry/utils/withConfig';
import {getThresholdUnits} from 'sentry/views/alerts/rules/metric/constants';
-import ThresholdControl from 'sentry/views/alerts/rules/metric/triggers/thresholdControl';
+import {ThresholdControl} from 'sentry/views/alerts/rules/metric/triggers/thresholdControl';
import type {
AlertRuleThresholdType,
ThresholdControlValue,
diff --git a/static/app/views/alerts/rules/metric/triggers/index.tsx b/static/app/views/alerts/rules/metric/triggers/index.tsx
index 2a77c322b4037e..be6d193830a9e3 100644
--- a/static/app/views/alerts/rules/metric/triggers/index.tsx
+++ b/static/app/views/alerts/rules/metric/triggers/index.tsx
@@ -7,7 +7,7 @@ import type {Project} from 'sentry/types/project';
import {removeAtArrayIndex} from 'sentry/utils/array/removeAtArrayIndex';
import {replaceAtArrayIndex} from 'sentry/utils/array/replaceAtArrayIndex';
import ActionsPanel from 'sentry/views/alerts/rules/metric/triggers/actionsPanel';
-import AnomalyDetectionFormField from 'sentry/views/alerts/rules/metric/triggers/anomalyAlertsForm';
+import {AnomalyDetectionFormField} from 'sentry/views/alerts/rules/metric/triggers/anomalyAlertsForm';
import {DynamicAlertsFeedbackButton} from 'sentry/views/alerts/rules/metric/triggers/dynamicAlertsFeedbackButton';
import TriggerForm from 'sentry/views/alerts/rules/metric/triggers/form';
import {
@@ -51,7 +51,7 @@ type Props = {
/**
* A list of forms to add, edit, and delete triggers.
*/
-class Triggers extends Component {
+export class Triggers extends Component {
handleDeleteTrigger = (index: number) => {
const {triggers, onChange} = this.props;
const updatedTriggers = removeAtArrayIndex(triggers, index);
@@ -169,5 +169,3 @@ class Triggers extends Component {
);
}
}
-
-export default Triggers;
diff --git a/static/app/views/alerts/rules/metric/triggers/thresholdControl.tsx b/static/app/views/alerts/rules/metric/triggers/thresholdControl.tsx
index 5adf711b8dd554..27d5efcb62ba74 100644
--- a/static/app/views/alerts/rules/metric/triggers/thresholdControl.tsx
+++ b/static/app/views/alerts/rules/metric/triggers/thresholdControl.tsx
@@ -27,7 +27,7 @@ type State = {
currentValue: string | null;
};
-class ThresholdControl extends Component {
+export class ThresholdControl extends Component {
state: State = {
currentValue: null,
};
@@ -186,5 +186,3 @@ const ThresholdContainer = styled('div')<{comparisonType: AlertRuleComparisonTyp
const PercentWrapper = styled('div')`
margin-left: ${p => p.theme.space.md};
`;
-
-export default ThresholdControl;
diff --git a/static/app/views/alerts/rules/uptime/assertions/assertionFailure/assertionFailureTree.tsx b/static/app/views/alerts/rules/uptime/assertions/assertionFailure/assertionFailureTree.tsx
index 0fd445e1ddf57d..f0883010e8f13f 100644
--- a/static/app/views/alerts/rules/uptime/assertions/assertionFailure/assertionFailureTree.tsx
+++ b/static/app/views/alerts/rules/uptime/assertions/assertionFailure/assertionFailureTree.tsx
@@ -3,7 +3,7 @@ import styled from '@emotion/styled';
import {Container, Flex} from '@sentry/scraps/layout';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {t} from 'sentry/locale';
import type {UptimeAssertion} from 'sentry/views/alerts/rules/uptime/types';
diff --git a/static/app/views/alerts/utils/getMetricRuleDiscoverUrl.tsx b/static/app/views/alerts/utils/getMetricRuleDiscoverUrl.tsx
index 9616c1fa55a1d6..ae1b6766b7ecd8 100644
--- a/static/app/views/alerts/utils/getMetricRuleDiscoverUrl.tsx
+++ b/static/app/views/alerts/utils/getMetricRuleDiscoverUrl.tsx
@@ -1,6 +1,6 @@
import type {NewQuery, Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {getAggregateAlias} from 'sentry/utils/discover/fields';
import type {SavedQueryDatasets} from 'sentry/utils/discover/types';
import type {TimePeriodType} from 'sentry/views/alerts/rules/metric/details/constants';
diff --git a/static/app/views/app/index.tsx b/static/app/views/app/index.tsx
index 8904d05be8fee7..7e0137300581bf 100644
--- a/static/app/views/app/index.tsx
+++ b/static/app/views/app/index.tsx
@@ -9,7 +9,7 @@ import {
import {fetchGuides} from 'sentry/actionCreators/guides';
import {fetchOrganizations} from 'sentry/actionCreators/organizations';
import {initApiClientErrorHandling} from 'sentry/api';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {GlobalModal} from 'sentry/components/globalModal';
import Hook from 'sentry/components/hook';
import Indicators from 'sentry/components/indicators';
diff --git a/static/app/views/automations/detail.tsx b/static/app/views/automations/detail.tsx
index 19b9898e9453c6..1f63be36ac67dd 100644
--- a/static/app/views/automations/detail.tsx
+++ b/static/app/views/automations/detail.tsx
@@ -7,7 +7,7 @@ import {Flex} from '@sentry/scraps/layout';
import {addSuccessMessage} from 'sentry/actionCreators/indicator';
import {Breadcrumbs} from 'sentry/components/breadcrumbs';
import {DateTime} from 'sentry/components/dateTime';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {KeyValueTable, KeyValueTableRow} from 'sentry/components/keyValueTable';
import {LoadingError} from 'sentry/components/loadingError';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
diff --git a/static/app/views/dashboards/create.tsx b/static/app/views/dashboards/create.tsx
index 93467950a9615a..6b97b7d333370c 100644
--- a/static/app/views/dashboards/create.tsx
+++ b/static/app/views/dashboards/create.tsx
@@ -3,7 +3,7 @@ import {useState} from 'react';
import {Alert} from '@sentry/scraps/alert';
import Feature from 'sentry/components/acl/feature';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import * as Layout from 'sentry/components/layouts/thirds';
import {t} from 'sentry/locale';
import {useLocation} from 'sentry/utils/useLocation';
diff --git a/static/app/views/dashboards/createFromSeer.tsx b/static/app/views/dashboards/createFromSeer.tsx
index 7ae7997d3697e1..b0f7fe4fbca714 100644
--- a/static/app/views/dashboards/createFromSeer.tsx
+++ b/static/app/views/dashboards/createFromSeer.tsx
@@ -5,7 +5,7 @@ import {Alert} from '@sentry/scraps/alert';
import {validateDashboard} from 'sentry/actionCreators/dashboards';
import {addErrorMessage} from 'sentry/actionCreators/indicator';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import * as Layout from 'sentry/components/layouts/thirds';
import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
diff --git a/static/app/views/dashboards/dashboard.spec.tsx b/static/app/views/dashboards/dashboard.spec.tsx
index 40d2407a3212a0..5148eb102c8c26 100644
--- a/static/app/views/dashboards/dashboard.spec.tsx
+++ b/static/app/views/dashboards/dashboard.spec.tsx
@@ -19,7 +19,7 @@ import type {DashboardDetails, Widget} from 'sentry/views/dashboards/types';
import {DisplayType, WidgetType} from 'sentry/views/dashboards/types';
import {getSavedFiltersAsPageFilters} from 'sentry/views/dashboards/utils';
-import WidgetLegendSelectionState from './widgetLegendSelectionState';
+import {WidgetLegendSelectionState} from './widgetLegendSelectionState';
jest.mock('sentry/components/lazyRender', () => ({
LazyRender: ({children}: {children: React.ReactNode}) => children,
diff --git a/static/app/views/dashboards/dashboard.tsx b/static/app/views/dashboards/dashboard.tsx
index 89fa85c68ef3bf..12e4f0534f7916 100644
--- a/static/app/views/dashboards/dashboard.tsx
+++ b/static/app/views/dashboards/dashboard.tsx
@@ -50,7 +50,7 @@ import {SortableWidget} from './sortableWidget';
import type {DashboardDetails, Widget} from './types';
import {DashboardFilterKeys, WidgetType} from './types';
import {connectDashboardCharts, getDashboardFiltersFromURL} from './utils';
-import type WidgetLegendSelectionState from './widgetLegendSelectionState';
+import type {WidgetLegendSelectionState} from './widgetLegendSelectionState';
export const DRAG_HANDLE_CLASS = 'widget-drag';
const DRAG_RESIZE_CLASS = 'widget-resize';
diff --git a/static/app/views/dashboards/datasetConfig/errors.spec.tsx b/static/app/views/dashboards/datasetConfig/errors.spec.tsx
index d638341b070286..e8e9f9d9a55478 100644
--- a/static/app/views/dashboards/datasetConfig/errors.spec.tsx
+++ b/static/app/views/dashboards/datasetConfig/errors.spec.tsx
@@ -7,7 +7,7 @@ import {UserFixture} from 'sentry-fixture/user';
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import type {EventViewOptions} from 'sentry/utils/discover/eventView';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {ErrorsConfig} from 'sentry/views/dashboards/datasetConfig/errors';
const theme = ThemeFixture();
diff --git a/static/app/views/dashboards/datasetConfig/errorsAndTransactions.spec.tsx b/static/app/views/dashboards/datasetConfig/errorsAndTransactions.spec.tsx
index b2c11f74777f19..47c45d0d9c6e1f 100644
--- a/static/app/views/dashboards/datasetConfig/errorsAndTransactions.spec.tsx
+++ b/static/app/views/dashboards/datasetConfig/errorsAndTransactions.spec.tsx
@@ -9,7 +9,7 @@ import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import type {TableData} from 'sentry/utils/discover/discoverQuery';
import type {EventViewOptions} from 'sentry/utils/discover/eventView';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {
getCustomEventsFieldRenderer,
transformEventsResponseToTable,
diff --git a/static/app/views/dashboards/datasetConfig/spans.spec.tsx b/static/app/views/dashboards/datasetConfig/spans.spec.tsx
index 5d261e3bda5fd8..6c3d98a91d4645 100644
--- a/static/app/views/dashboards/datasetConfig/spans.spec.tsx
+++ b/static/app/views/dashboards/datasetConfig/spans.spec.tsx
@@ -13,7 +13,7 @@ import type {
Organization,
} from 'sentry/types/organization';
import type {EventViewOptions} from 'sentry/utils/discover/eventView';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {ALLOWED_EXPLORE_VISUALIZE_AGGREGATES} from 'sentry/utils/fields';
import {SpansConfig} from 'sentry/views/dashboards/datasetConfig/spans';
import {DisplayType, type WidgetQuery} from 'sentry/views/dashboards/types';
diff --git a/static/app/views/dashboards/detail.tsx b/static/app/views/dashboards/detail.tsx
index 87ad4a02570076..f093953a3d9c34 100644
--- a/static/app/views/dashboards/detail.tsx
+++ b/static/app/views/dashboards/detail.tsx
@@ -40,7 +40,7 @@ import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
import {browserHistory} from 'sentry/utils/browserHistory';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MetricsCardinalityProvider} from 'sentry/utils/performance/contexts/metricsCardinality';
import {MetricsResultsMetaProvider} from 'sentry/utils/performance/contexts/metricsEnhancedPerformanceDataContext';
import {MEPSettingProvider} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
@@ -102,7 +102,7 @@ import type {
Widget,
} from './types';
import {DashboardFilterKeys, DashboardState, MAX_WIDGETS, WidgetType} from './types';
-import WidgetLegendSelectionState from './widgetLegendSelectionState';
+import {WidgetLegendSelectionState} from './widgetLegendSelectionState';
const UNSAVED_MESSAGE = t('You have unsaved changes, are you sure you want to leave?');
diff --git a/static/app/views/dashboards/index.tsx b/static/app/views/dashboards/index.tsx
index 13d901a651ec53..d6e2757acf7753 100644
--- a/static/app/views/dashboards/index.tsx
+++ b/static/app/views/dashboards/index.tsx
@@ -1,7 +1,7 @@
import {Fragment} from 'react';
import {Outlet} from 'react-router-dom';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {NotFound} from 'sentry/components/errors/notFound';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {useOrganization} from 'sentry/utils/useOrganization';
diff --git a/static/app/views/dashboards/manage/index.tsx b/static/app/views/dashboards/manage/index.tsx
index 8d9711fb6e8aea..53ff00990f0b39 100644
--- a/static/app/views/dashboards/manage/index.tsx
+++ b/static/app/views/dashboards/manage/index.tsx
@@ -19,7 +19,7 @@ import {addLoadingMessage, addSuccessMessage} from 'sentry/actionCreators/indica
import {openImportDashboardFromFileModal} from 'sentry/actionCreators/modal';
import Feature from 'sentry/components/acl/feature';
import {DropdownMenu} from 'sentry/components/dropdownMenu';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {FeedbackButton} from 'sentry/components/feedbackButton/feedbackButton';
import * as Layout from 'sentry/components/layouts/thirds';
import {NoProjectMessage} from 'sentry/components/noProjectMessage';
diff --git a/static/app/views/dashboards/sortableWidget.tsx b/static/app/views/dashboards/sortableWidget.tsx
index 70cfe61f91f4cc..6af739810b4459 100644
--- a/static/app/views/dashboards/sortableWidget.tsx
+++ b/static/app/views/dashboards/sortableWidget.tsx
@@ -25,7 +25,7 @@ import {
type Widget,
type WidgetQuery,
} from './types';
-import type WidgetLegendSelectionState from './widgetLegendSelectionState';
+import type {WidgetLegendSelectionState} from './widgetLegendSelectionState';
const TABLE_ITEM_LIMIT = 20;
diff --git a/static/app/views/dashboards/utils.tsx b/static/app/views/dashboards/utils.tsx
index f6b3c21091152c..67f9202ce9898b 100644
--- a/static/app/views/dashboards/utils.tsx
+++ b/static/app/views/dashboards/utils.tsx
@@ -22,7 +22,7 @@ import type {Organization} from 'sentry/types/organization';
import {defined} from 'sentry/utils';
import {browserHistory} from 'sentry/utils/browserHistory';
import {getUtcDateString} from 'sentry/utils/dates';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DURATION_UNITS} from 'sentry/utils/discover/fieldRenderers';
import {
ABYTE_UNITS,
diff --git a/static/app/views/dashboards/view.tsx b/static/app/views/dashboards/view.tsx
index eb5ba3f8066e00..77a79023d2395b 100644
--- a/static/app/views/dashboards/view.tsx
+++ b/static/app/views/dashboards/view.tsx
@@ -4,7 +4,7 @@ import {Alert} from '@sentry/scraps/alert';
import {updateDashboardVisit} from 'sentry/actionCreators/dashboards';
import Feature from 'sentry/components/acl/feature';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {NotFound} from 'sentry/components/errors/notFound';
import * as Layout from 'sentry/components/layouts/thirds';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
diff --git a/static/app/views/dashboards/widgetBuilder/components/datasetSelector.tsx b/static/app/views/dashboards/widgetBuilder/components/datasetSelector.tsx
index 7edba8cc9deb02..ec7323589be034 100644
--- a/static/app/views/dashboards/widgetBuilder/components/datasetSelector.tsx
+++ b/static/app/views/dashboards/widgetBuilder/components/datasetSelector.tsx
@@ -4,7 +4,7 @@ import * as Sentry from '@sentry/react';
import {CompactSelect} from '@sentry/scraps/compactSelect';
-import ExternalLink from 'sentry/components/links/externalLink';
+import {ExternalLink} from 'sentry/components/links/externalLink';
import {t, tct, tctCode} from 'sentry/locale';
import {trackAnalytics} from 'sentry/utils/analytics';
import {WidgetBuilderVersion} from 'sentry/utils/analytics/dashboardsAnalyticsEvents';
diff --git a/static/app/views/dashboards/widgetBuilder/components/newWidgetBuilder.tsx b/static/app/views/dashboards/widgetBuilder/components/newWidgetBuilder.tsx
index 8ea4b28f8423f2..3434106587d9d2 100644
--- a/static/app/views/dashboards/widgetBuilder/components/newWidgetBuilder.tsx
+++ b/static/app/views/dashboards/widgetBuilder/components/newWidgetBuilder.tsx
@@ -17,7 +17,7 @@ import {Flex} from '@sentry/scraps/layout';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import {t} from 'sentry/locale';
import {CustomMeasurementsProvider} from 'sentry/utils/customMeasurements/customMeasurementsProvider';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MetricsCardinalityProvider} from 'sentry/utils/performance/contexts/metricsCardinality';
import {MEPSettingProvider} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
import {useDimensions} from 'sentry/utils/useDimensions';
diff --git a/static/app/views/dashboards/widgetBuilder/components/widgetBuilderSlideout.tsx b/static/app/views/dashboards/widgetBuilder/components/widgetBuilderSlideout.tsx
index cefa373b20479e..b17494c071277b 100644
--- a/static/app/views/dashboards/widgetBuilder/components/widgetBuilderSlideout.tsx
+++ b/static/app/views/dashboards/widgetBuilder/components/widgetBuilderSlideout.tsx
@@ -18,7 +18,7 @@ import {SlideOverPanel} from '@sentry/scraps/slideOverPanel';
import {Breadcrumbs} from 'sentry/components/breadcrumbs';
import {openConfirmModal} from 'sentry/components/confirm';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {Placeholder} from 'sentry/components/placeholder';
import {IconClose} from 'sentry/icons';
import {t, tctCode} from 'sentry/locale';
diff --git a/static/app/views/dashboards/widgetBuilder/components/widgetPreview.tsx b/static/app/views/dashboards/widgetBuilder/components/widgetPreview.tsx
index 4f20daa8b3ae48..5f4909a8c4b49f 100644
--- a/static/app/views/dashboards/widgetBuilder/components/widgetPreview.tsx
+++ b/static/app/views/dashboards/widgetBuilder/components/widgetPreview.tsx
@@ -20,7 +20,7 @@ import {convertBuilderStateToWidget} from 'sentry/views/dashboards/widgetBuilder
import type {OnDataFetchedParams} from 'sentry/views/dashboards/widgetCard';
import WidgetCard from 'sentry/views/dashboards/widgetCard';
import {WidgetLegendNameEncoderDecoder} from 'sentry/views/dashboards/widgetLegendNameEncoderDecoder';
-import WidgetLegendSelectionState from 'sentry/views/dashboards/widgetLegendSelectionState';
+import {WidgetLegendSelectionState} from 'sentry/views/dashboards/widgetLegendSelectionState';
import type {TabularColumn} from 'sentry/views/dashboards/widgets/common/types';
interface WidgetPreviewProps {
diff --git a/static/app/views/dashboards/widgetCard/chart.tsx b/static/app/views/dashboards/widgetCard/chart.tsx
index 0dd6def32bb091..b7de3f86229c70 100644
--- a/static/app/views/dashboards/widgetCard/chart.tsx
+++ b/static/app/views/dashboards/widgetCard/chart.tsx
@@ -12,7 +12,7 @@ import {getFormatter} from 'sentry/components/charts/components/tooltip';
import {ErrorPanel} from 'sentry/components/charts/errorPanel';
import {LineChart} from 'sentry/components/charts/lineChart';
import ReleaseSeries from 'sentry/components/charts/releaseSeries';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
import {getSeriesSelection, isChartHovered} from 'sentry/components/charts/utils';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
@@ -72,7 +72,7 @@ import {getBucketSize} from 'sentry/views/dashboards/utils/getBucketSize';
import {getWidgetTableRowExploreUrlFunction} from 'sentry/views/dashboards/utils/getWidgetExploreUrl';
import {getSelectedAggregateIndex} from 'sentry/views/dashboards/widgetBuilder/utils/convertBuilderStateToWidget';
import {WidgetLegendNameEncoderDecoder} from 'sentry/views/dashboards/widgetLegendNameEncoderDecoder';
-import type WidgetLegendSelectionState from 'sentry/views/dashboards/widgetLegendSelectionState';
+import type {WidgetLegendSelectionState} from 'sentry/views/dashboards/widgetLegendSelectionState';
import {AgentsTracesTableWidgetVisualization} from 'sentry/views/dashboards/widgets/agentsTracesTableWidget/agentsTracesTableWidgetVisualization';
import {BigNumberWidgetVisualization} from 'sentry/views/dashboards/widgets/bigNumberWidget/bigNumberWidgetVisualization';
import {CategoricalSeriesWidgetVisualization} from 'sentry/views/dashboards/widgets/categoricalSeriesWidget/categoricalSeriesWidgetVisualization';
diff --git a/static/app/views/dashboards/widgetCard/index.spec.tsx b/static/app/views/dashboards/widgetCard/index.spec.tsx
index 94fb2ca11196f1..29c2e5e85d3cef 100644
--- a/static/app/views/dashboards/widgetCard/index.spec.tsx
+++ b/static/app/views/dashboards/widgetCard/index.spec.tsx
@@ -25,7 +25,7 @@ import {
} from 'sentry/views/dashboards/types';
import WidgetCard from 'sentry/views/dashboards/widgetCard';
import {ReleaseWidgetQueries} from 'sentry/views/dashboards/widgetCard/releaseWidgetQueries';
-import WidgetLegendSelectionState from 'sentry/views/dashboards/widgetLegendSelectionState';
+import {WidgetLegendSelectionState} from 'sentry/views/dashboards/widgetLegendSelectionState';
import {TableWidgetVisualization} from 'sentry/views/dashboards/widgets/tableWidget/tableWidgetVisualization';
import {DashboardsMEPProvider} from './dashboardsMEPContext';
diff --git a/static/app/views/dashboards/widgetCard/index.tsx b/static/app/views/dashboards/widgetCard/index.tsx
index 5b3af83e7c6f43..f2186e76a10c06 100644
--- a/static/app/views/dashboards/widgetCard/index.tsx
+++ b/static/app/views/dashboards/widgetCard/index.tsx
@@ -7,7 +7,7 @@ import omit from 'lodash/omit';
import {openWidgetViewerModal} from 'sentry/actionCreators/modal';
import type {Client} from 'sentry/api';
import {DateTime} from 'sentry/components/dateTime';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {
isWidgetViewerPath,
WidgetViewerQueryField,
@@ -49,7 +49,7 @@ import {
} from 'sentry/views/dashboards/types';
import {widgetCanUseTimeSeriesVisualization} from 'sentry/views/dashboards/utils/widgetCanUseTimeSeriesVisualization';
import {WidgetCardChartContainer} from 'sentry/views/dashboards/widgetCard/widgetCardChartContainer';
-import type WidgetLegendSelectionState from 'sentry/views/dashboards/widgetLegendSelectionState';
+import type {WidgetLegendSelectionState} from 'sentry/views/dashboards/widgetLegendSelectionState';
import type {TabularColumn} from 'sentry/views/dashboards/widgets/common/types';
import {Widget} from 'sentry/views/dashboards/widgets/widget/widget';
diff --git a/static/app/views/dashboards/widgetCard/widgetCardChartContainer.tsx b/static/app/views/dashboards/widgetCard/widgetCardChartContainer.tsx
index 42738a7cc43e1c..a5d48de2727bb7 100644
--- a/static/app/views/dashboards/widgetCard/widgetCardChartContainer.tsx
+++ b/static/app/views/dashboards/widgetCard/widgetCardChartContainer.tsx
@@ -18,7 +18,7 @@ import type {DashboardFilters, Widget as TWidget} from 'sentry/views/dashboards/
import {DisplayType, WidgetType} from 'sentry/views/dashboards/types';
import {usesTimeSeriesData, widgetFetchesOwnData} from 'sentry/views/dashboards/utils';
import {WidgetLegendNameEncoderDecoder} from 'sentry/views/dashboards/widgetLegendNameEncoderDecoder';
-import type WidgetLegendSelectionState from 'sentry/views/dashboards/widgetLegendSelectionState';
+import type {WidgetLegendSelectionState} from 'sentry/views/dashboards/widgetLegendSelectionState';
import type {TabularColumn} from 'sentry/views/dashboards/widgets/common/types';
import {Widget} from 'sentry/views/dashboards/widgets/widget/widget';
diff --git a/static/app/views/dashboards/widgetLegendSelectionState.spec.tsx b/static/app/views/dashboards/widgetLegendSelectionState.spec.tsx
index 24da8df7b394c9..2d64c4e5ba7df9 100644
--- a/static/app/views/dashboards/widgetLegendSelectionState.spec.tsx
+++ b/static/app/views/dashboards/widgetLegendSelectionState.spec.tsx
@@ -7,7 +7,7 @@ import type {Organization} from 'sentry/types/organization';
import type {DashboardDetails, Widget} from 'sentry/views/dashboards/types';
import {DisplayType, WidgetType} from 'sentry/views/dashboards/types';
-import WidgetLegendSelectionState from './widgetLegendSelectionState';
+import {WidgetLegendSelectionState} from './widgetLegendSelectionState';
const WIDGET_ID_DELIMITER = ':';
const SERIES_NAME_DELIMITER = '|~|';
diff --git a/static/app/views/dashboards/widgetLegendSelectionState.tsx b/static/app/views/dashboards/widgetLegendSelectionState.tsx
index 5404b6936a095d..88dd694fbacd33 100644
--- a/static/app/views/dashboards/widgetLegendSelectionState.tsx
+++ b/static/app/views/dashboards/widgetLegendSelectionState.tsx
@@ -21,7 +21,7 @@ const WIDGET_ID_DELIMITER = ':';
const SERIES_NAME_DELIMITER = '|~|';
-class WidgetLegendSelectionState {
+export class WidgetLegendSelectionState {
dashboard: DashboardDetails | null;
location: Location;
organization: Organization;
@@ -270,5 +270,3 @@ class WidgetLegendSelectionState {
return unselectedSeries;
}
}
-
-export default WidgetLegendSelectionState;
diff --git a/static/app/views/dashboards/widgets/widget/widget.tsx b/static/app/views/dashboards/widgets/widget/widget.tsx
index 4505edc0c917dc..393d2f7ad89df1 100644
--- a/static/app/views/dashboards/widgets/widget/widget.tsx
+++ b/static/app/views/dashboards/widgets/widget/widget.tsx
@@ -4,7 +4,7 @@ import styled from '@emotion/styled';
import {Container, Flex} from '@sentry/scraps/layout';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {defined} from 'sentry/utils';
import {MIN_HEIGHT, MIN_WIDTH} from 'sentry/views/dashboards/widgets/common/settings';
diff --git a/static/app/views/detectors/components/details/common/automations.tsx b/static/app/views/detectors/components/details/common/automations.tsx
index f32be03a250349..73ebcc26931249 100644
--- a/static/app/views/detectors/components/details/common/automations.tsx
+++ b/static/app/views/detectors/components/details/common/automations.tsx
@@ -7,7 +7,7 @@ import {Link} from '@sentry/scraps/link';
import {Tooltip} from '@sentry/scraps/tooltip';
import {addLoadingMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {useDrawer} from 'sentry/components/globalDrawer';
import {LoadingError} from 'sentry/components/loadingError';
import {Pagination} from 'sentry/components/pagination';
diff --git a/static/app/views/detectors/components/details/common/ongoingIssues.tsx b/static/app/views/detectors/components/details/common/ongoingIssues.tsx
index 3726aa1974d915..33b75319de9e63 100644
--- a/static/app/views/detectors/components/details/common/ongoingIssues.tsx
+++ b/static/app/views/detectors/components/details/common/ongoingIssues.tsx
@@ -1,6 +1,6 @@
import {LinkButton} from '@sentry/scraps/button';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {GroupList} from 'sentry/components/issues/groupList';
import {Section} from 'sentry/components/workflowEngine/ui/section';
import {t} from 'sentry/locale';
diff --git a/static/app/views/detectors/components/details/common/openPeriodIssues.tsx b/static/app/views/detectors/components/details/common/openPeriodIssues.tsx
index 0258f37d37cc1d..11d22a2e8b37c0 100644
--- a/static/app/views/detectors/components/details/common/openPeriodIssues.tsx
+++ b/static/app/views/detectors/components/details/common/openPeriodIssues.tsx
@@ -7,7 +7,7 @@ import {Text} from '@sentry/scraps/text';
import {DateTime} from 'sentry/components/dateTime';
import {Duration} from 'sentry/components/duration';
import {EmptyStateWarning} from 'sentry/components/emptyStateWarning';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {
AssigneeSelector,
useHandleAssigneeChange,
diff --git a/static/app/views/detectors/components/details/cron/index.tsx b/static/app/views/detectors/components/details/cron/index.tsx
index b1a3f4f8994c41..48e0b653a9c973 100644
--- a/static/app/views/detectors/components/details/cron/index.tsx
+++ b/static/app/views/detectors/components/details/cron/index.tsx
@@ -7,7 +7,7 @@ import {Flex} from '@sentry/scraps/layout';
import {Text} from '@sentry/scraps/text';
import {CopyToClipboardButton} from 'sentry/components/copyToClipboardButton';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {useDrawer} from 'sentry/components/globalDrawer';
import {DrawerBody, DrawerHeader} from 'sentry/components/globalDrawer/components';
import {KeyValueTableRow} from 'sentry/components/keyValueTable';
diff --git a/static/app/views/detectors/components/details/fallback.tsx b/static/app/views/detectors/components/details/fallback.tsx
index 9d52761e47b394..dea5b6c533403f 100644
--- a/static/app/views/detectors/components/details/fallback.tsx
+++ b/static/app/views/detectors/components/details/fallback.tsx
@@ -1,4 +1,4 @@
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {DetailLayout} from 'sentry/components/workflowEngine/layout/detail';
import type {Project} from 'sentry/types/project';
import type {Detector} from 'sentry/types/workflowEngine/detectors';
diff --git a/static/app/views/detectors/components/details/metric/getDetectorOpenInDestination.tsx b/static/app/views/detectors/components/details/metric/getDetectorOpenInDestination.tsx
index 416fce8f7778bb..d04ae272c6f8f7 100644
--- a/static/app/views/detectors/components/details/metric/getDetectorOpenInDestination.tsx
+++ b/static/app/views/detectors/components/details/metric/getDetectorOpenInDestination.tsx
@@ -4,7 +4,7 @@ import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import type {SnubaQuery} from 'sentry/types/workflowEngine/detectors';
import {defined} from 'sentry/utils';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {getAggregateAlias, parseFunction} from 'sentry/utils/discover/fields';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {normalizeUrl} from 'sentry/utils/url/normalizeUrl';
diff --git a/static/app/views/detectors/components/details/metric/index.tsx b/static/app/views/detectors/components/details/metric/index.tsx
index 6c1289c965b237..45c23628c6e105 100644
--- a/static/app/views/detectors/components/details/metric/index.tsx
+++ b/static/app/views/detectors/components/details/metric/index.tsx
@@ -1,4 +1,4 @@
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {DetailLayout} from 'sentry/components/workflowEngine/layout/detail';
import {t} from 'sentry/locale';
import type {Project} from 'sentry/types/project';
diff --git a/static/app/views/detectors/components/details/metric/sidebar.tsx b/static/app/views/detectors/components/details/metric/sidebar.tsx
index 5b251048e4bbfc..c5bbfea5880e0a 100644
--- a/static/app/views/detectors/components/details/metric/sidebar.tsx
+++ b/static/app/views/detectors/components/details/metric/sidebar.tsx
@@ -3,7 +3,7 @@ import {Link} from 'react-router-dom';
import {Tooltip} from '@sentry/scraps/tooltip';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {Section} from 'sentry/components/workflowEngine/ui/section';
import {t} from 'sentry/locale';
import type {MetricDetector} from 'sentry/types/workflowEngine/detectors';
diff --git a/static/app/views/detectors/components/details/mobileBuild/index.tsx b/static/app/views/detectors/components/details/mobileBuild/index.tsx
index c968a157240149..69f2fcab22c9bf 100644
--- a/static/app/views/detectors/components/details/mobileBuild/index.tsx
+++ b/static/app/views/detectors/components/details/mobileBuild/index.tsx
@@ -1,4 +1,4 @@
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {DetailLayout} from 'sentry/components/workflowEngine/layout/detail';
import {t} from 'sentry/locale';
import type {Project} from 'sentry/types/project';
diff --git a/static/app/views/detectors/components/details/mobileBuild/sidebar.tsx b/static/app/views/detectors/components/details/mobileBuild/sidebar.tsx
index e969c8c709bd25..e7cc965febc072 100644
--- a/static/app/views/detectors/components/details/mobileBuild/sidebar.tsx
+++ b/static/app/views/detectors/components/details/mobileBuild/sidebar.tsx
@@ -1,6 +1,6 @@
import {Fragment} from 'react';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {Section} from 'sentry/components/workflowEngine/ui/section';
import {t} from 'sentry/locale';
import type {PreprodDetector} from 'sentry/types/workflowEngine/detectors';
diff --git a/static/app/views/detectors/components/detectorLink.tsx b/static/app/views/detectors/components/detectorLink.tsx
index 0404116762bdb0..c3cdb03a011eb1 100644
--- a/static/app/views/detectors/components/detectorLink.tsx
+++ b/static/app/views/detectors/components/detectorLink.tsx
@@ -3,7 +3,7 @@ import {css} from '@emotion/react';
import styled from '@emotion/styled';
import pick from 'lodash/pick';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import ProjectBadge from 'sentry/components/idBadge/projectBadge';
import {TitleCell} from 'sentry/components/workflowEngine/gridCell/titleCell';
import {t, tct} from 'sentry/locale';
diff --git a/static/app/views/discover/breadcrumb.tsx b/static/app/views/discover/breadcrumb.tsx
index b8c9894f262f6a..bf243b895f1ff5 100644
--- a/static/app/views/discover/breadcrumb.tsx
+++ b/static/app/views/discover/breadcrumb.tsx
@@ -7,7 +7,7 @@ import {t} from 'sentry/locale';
import type {Event} from 'sentry/types/event';
import type {Organization} from 'sentry/types/organization';
import {defined} from 'sentry/utils';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {getDiscoverLandingUrl} from 'sentry/utils/discover/urls';
import {makeDiscoverPathname} from 'sentry/views/discover/pathnames';
diff --git a/static/app/views/discover/eventInputName.tsx b/static/app/views/discover/eventInputName.tsx
index a206db5fa27698..65724ee0fa4f74 100644
--- a/static/app/views/discover/eventInputName.tsx
+++ b/static/app/views/discover/eventInputName.tsx
@@ -2,7 +2,7 @@ import {EditableText} from 'sentry/components/editableText';
import * as Layout from 'sentry/components/layouts/thirds';
import {t} from 'sentry/locale';
import type {Organization, SavedQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {normalizeUrl} from 'sentry/utils/url/normalizeUrl';
import {useApi} from 'sentry/utils/useApi';
import {useNavigate} from 'sentry/utils/useNavigate';
diff --git a/static/app/views/discover/homepage.spec.tsx b/static/app/views/discover/homepage.spec.tsx
index f2eff988623374..85c9609614c155 100644
--- a/static/app/views/discover/homepage.spec.tsx
+++ b/static/app/views/discover/homepage.spec.tsx
@@ -13,7 +13,7 @@ import {
import * as pageFilterUtils from 'sentry/components/pageFilters/persistence';
import {ProjectsStore} from 'sentry/stores/projectsStore';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DEFAULT_EVENT_VIEW} from 'sentry/views/discover/results/data';
import Homepage from './homepage';
diff --git a/static/app/views/discover/homepage.tsx b/static/app/views/discover/homepage.tsx
index fb4a9c95090520..fee5d94c275c54 100644
--- a/static/app/views/discover/homepage.tsx
+++ b/static/app/views/discover/homepage.tsx
@@ -11,7 +11,7 @@ import {getPageFilterStorage} from 'sentry/components/pageFilters/persistence';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import type {Organization, SavedQuery} from 'sentry/types/organization';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {useApiQuery, useQueryClient, type ApiQueryKey} from 'sentry/utils/queryClient';
import {useApi} from 'sentry/utils/useApi';
import {useLocation} from 'sentry/utils/useLocation';
diff --git a/static/app/views/discover/landing.tsx b/static/app/views/discover/landing.tsx
index f87d20d9e0411a..6ba57d02acaba7 100644
--- a/static/app/views/discover/landing.tsx
+++ b/static/app/views/discover/landing.tsx
@@ -19,7 +19,7 @@ import type {SelectValue} from 'sentry/types/core';
import type {NewQuery, SavedQuery} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {getDiscoverLandingUrl} from 'sentry/utils/discover/urls';
import {useApiQuery} from 'sentry/utils/queryClient';
import {decodeScalar} from 'sentry/utils/queryString';
diff --git a/static/app/views/discover/miniGraph.spec.tsx b/static/app/views/discover/miniGraph.spec.tsx
index 5e90d567c8bd63..754281d4a43242 100644
--- a/static/app/views/discover/miniGraph.spec.tsx
+++ b/static/app/views/discover/miniGraph.spec.tsx
@@ -3,8 +3,8 @@ import {OrganizationFixture} from 'sentry-fixture/organization';
import {render} from 'sentry-test/reactTestingLibrary';
-import * as eventRequest from 'sentry/components/charts/eventsRequest';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventsRequest} from 'sentry/components/charts/eventsRequest';
+import {EventView} from 'sentry/utils/discover/eventView';
import MiniGraph from 'sentry/views/discover/miniGraph';
jest.mock('sentry/components/charts/eventsRequest');
@@ -43,7 +43,7 @@ describe('Discover > MiniGraph', () => {
/>
);
- expect(eventRequest.default).toHaveBeenCalledWith(
+ expect(EventsRequest).toHaveBeenCalledWith(
expect.objectContaining({yAxis}),
expect.anything()
);
@@ -62,7 +62,7 @@ describe('Discover > MiniGraph', () => {
/>
);
- expect(eventRequest.default).toHaveBeenCalledWith(
+ expect(EventsRequest).toHaveBeenCalledWith(
expect.objectContaining({interval: '12h'}),
expect.anything()
);
diff --git a/static/app/views/discover/miniGraph.tsx b/static/app/views/discover/miniGraph.tsx
index 62cb33e9eea0ac..21f88ffeb8f3d5 100644
--- a/static/app/views/discover/miniGraph.tsx
+++ b/static/app/views/discover/miniGraph.tsx
@@ -10,7 +10,7 @@ import type {AreaChartProps} from 'sentry/components/charts/areaChart';
import {AreaChart} from 'sentry/components/charts/areaChart';
import type {BarChartProps} from 'sentry/components/charts/barChart';
import {BarChart} from 'sentry/components/charts/barChart';
-import EventsRequest from 'sentry/components/charts/eventsRequest';
+import {EventsRequest} from 'sentry/components/charts/eventsRequest';
import {LineChart} from 'sentry/components/charts/lineChart';
import {getInterval} from 'sentry/components/charts/utils';
import {LoadingContainer} from 'sentry/components/loading/loadingContainer';
@@ -20,7 +20,7 @@ import type {Series} from 'sentry/types/echarts';
import type {Organization} from 'sentry/types/organization';
import {getUtcToLocalDateObject} from 'sentry/utils/dates';
import {axisLabelFormatter} from 'sentry/utils/discover/charts';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {PlotType} from 'sentry/utils/discover/fields';
import {aggregateOutputType} from 'sentry/utils/discover/fields';
import {DisplayModes, TOP_N} from 'sentry/utils/discover/types';
diff --git a/static/app/views/discover/queryList.tsx b/static/app/views/discover/queryList.tsx
index bfb8929ae468a1..55200f90d96fd7 100644
--- a/static/app/views/discover/queryList.tsx
+++ b/static/app/views/discover/queryList.tsx
@@ -18,7 +18,7 @@ import {t} from 'sentry/locale';
import type {NewQuery, Organization, SavedQuery} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
import {browserHistory} from 'sentry/utils/browserHistory';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {SavedQueryDatasets} from 'sentry/utils/discover/types';
import {parseLinkHeader} from 'sentry/utils/parseLinkHeader';
import {decodeList} from 'sentry/utils/queryString';
@@ -34,7 +34,7 @@ import {
handleUpdateHomepageQuery,
} from './savedQuery/utils';
import MiniGraph from './miniGraph';
-import QueryCard from './querycard';
+import {QueryCard} from './querycard';
import {
getPrebuiltQueries,
handleAddQueryToDashboard,
diff --git a/static/app/views/discover/querycard.tsx b/static/app/views/discover/querycard.tsx
index 76fe2b5fd8c0bd..2b7c18c2d4d29a 100644
--- a/static/app/views/discover/querycard.tsx
+++ b/static/app/views/discover/querycard.tsx
@@ -5,7 +5,7 @@ import {Link} from '@sentry/scraps/link';
import {ActivityAvatar} from 'sentry/components/activity/item/avatar';
import {Card} from 'sentry/components/card';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {t} from 'sentry/locale';
import type {User} from 'sentry/types/user';
@@ -21,7 +21,7 @@ type Props = {
title?: string;
};
-class QueryCard extends PureComponent {
+export class QueryCard extends PureComponent {
handleClick = () => {
const {onEventClick} = this.props;
onEventClick?.();
@@ -160,5 +160,3 @@ const DateStatus = styled('span')`
const StyledErrorBoundary = styled(ErrorBoundary)`
margin-bottom: 100px;
`;
-
-export default QueryCard;
diff --git a/static/app/views/discover/results.spec.tsx b/static/app/views/discover/results.spec.tsx
index dcb4d3410bf926..b3bc4effbd38c0 100644
--- a/static/app/views/discover/results.spec.tsx
+++ b/static/app/views/discover/results.spec.tsx
@@ -8,7 +8,7 @@ import {selectEvent} from 'sentry-test/selectEvent';
import * as PageFilterPersistence from 'sentry/components/pageFilters/persistence';
import {ProjectsStore} from 'sentry/stores/projectsStore';
import {SavedSearchType} from 'sentry/types/group';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import Results from 'sentry/views/discover/results';
import {
DEFAULT_EVENT_VIEW,
diff --git a/static/app/views/discover/results.tsx b/static/app/views/discover/results.tsx
index b48698c2f8bc6b..cd36e27052ecf6 100644
--- a/static/app/views/discover/results.tsx
+++ b/static/app/views/discover/results.tsx
@@ -41,7 +41,7 @@ import {getApiUrl} from 'sentry/utils/api/getApiUrl';
import type {CustomMeasurementCollection} from 'sentry/utils/customMeasurements/customMeasurements';
import {CustomMeasurementsContext} from 'sentry/utils/customMeasurements/customMeasurementsContext';
import {CustomMeasurementsProvider} from 'sentry/utils/customMeasurements/customMeasurementsProvider';
-import EventView, {isAPIPayloadSimilar} from 'sentry/utils/discover/eventView';
+import {EventView, isAPIPayloadSimilar} from 'sentry/utils/discover/eventView';
import {formatTagKey, generateAggregateFields} from 'sentry/utils/discover/fields';
import {
DiscoverDatasets,
diff --git a/static/app/views/discover/results/chartFooter.spec.tsx b/static/app/views/discover/results/chartFooter.spec.tsx
index e8d2be35df290c..51fd103817ee31 100644
--- a/static/app/views/discover/results/chartFooter.spec.tsx
+++ b/static/app/views/discover/results/chartFooter.spec.tsx
@@ -2,7 +2,7 @@ import {ProjectFixture} from 'sentry-fixture/project';
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DisplayModes} from 'sentry/utils/discover/types';
import {ChartFooter} from 'sentry/views/discover/results/chartFooter';
diff --git a/static/app/views/discover/results/chartFooter.tsx b/static/app/views/discover/results/chartFooter.tsx
index 3d541cfa1ab0fb..72ccb71418fa60 100644
--- a/static/app/views/discover/results/chartFooter.tsx
+++ b/static/app/views/discover/results/chartFooter.tsx
@@ -8,7 +8,7 @@ import {
} from 'sentry/components/charts/styles';
import {t} from 'sentry/locale';
import type {SelectValue} from 'sentry/types/core';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {TOP_EVENT_MODES} from 'sentry/utils/discover/types';
type Props = {
diff --git a/static/app/views/discover/results/resultsChart.spec.tsx b/static/app/views/discover/results/resultsChart.spec.tsx
index c2e1f8646ff407..7a13a1f602eef4 100644
--- a/static/app/views/discover/results/resultsChart.spec.tsx
+++ b/static/app/views/discover/results/resultsChart.spec.tsx
@@ -3,7 +3,7 @@ import {OrganizationFixture} from 'sentry-fixture/organization';
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DISPLAY_MODE_OPTIONS, DisplayModes} from 'sentry/utils/discover/types';
import ResultsChart from 'sentry/views/discover/results/resultsChart';
diff --git a/static/app/views/discover/results/resultsChart.tsx b/static/app/views/discover/results/resultsChart.tsx
index 82ba94d3c0d3cb..a2ce8f9b742b39 100644
--- a/static/app/views/discover/results/resultsChart.tsx
+++ b/static/app/views/discover/results/resultsChart.tsx
@@ -6,7 +6,7 @@ import isEqual from 'lodash/isEqual';
import type {Client} from 'sentry/api';
import {AreaChart} from 'sentry/components/charts/areaChart';
import {BarChart} from 'sentry/components/charts/barChart';
-import EventsChart from 'sentry/components/charts/eventsChart';
+import {EventsChart} from 'sentry/components/charts/eventsChart';
import {getInterval, getPreviousSeriesName} from 'sentry/components/charts/utils';
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
import {Panel} from 'sentry/components/panels/panel';
@@ -17,7 +17,7 @@ import type {Organization} from 'sentry/types/organization';
import type {CustomMeasurementCollection} from 'sentry/utils/customMeasurements/customMeasurements';
import {CustomMeasurementsContext} from 'sentry/utils/customMeasurements/customMeasurementsContext';
import {getUtcToLocalDateObject} from 'sentry/utils/dates';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {getAggregateArg, stripEquationPrefix} from 'sentry/utils/discover/fields';
import {
DisplayModes,
diff --git a/static/app/views/discover/results/resultsHeader.tsx b/static/app/views/discover/results/resultsHeader.tsx
index 764dc9e2c0a225..be4157d5b4a964 100644
--- a/static/app/views/discover/results/resultsHeader.tsx
+++ b/static/app/views/discover/results/resultsHeader.tsx
@@ -11,7 +11,7 @@ import {PageHeadingQuestionTooltip} from 'sentry/components/pageHeadingQuestionT
import {TimeSince} from 'sentry/components/timeSince';
import {t} from 'sentry/locale';
import type {Organization, SavedQuery} from 'sentry/types/organization';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {SavedQueryDatasets} from 'sentry/utils/discover/types';
import {withApi} from 'sentry/utils/withApi';
import {DiscoverBreadcrumb} from 'sentry/views/discover/breadcrumb';
diff --git a/static/app/views/discover/results/tags.spec.tsx b/static/app/views/discover/results/tags.spec.tsx
index 31113094b44855..ae37169c81d058 100644
--- a/static/app/views/discover/results/tags.spec.tsx
+++ b/static/app/views/discover/results/tags.spec.tsx
@@ -10,7 +10,7 @@ import {
waitForElementToBeRemoved,
} from 'sentry-test/reactTestingLibrary';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {Tags} from 'sentry/views/discover/results/tags';
diff --git a/static/app/views/discover/results/tags.tsx b/static/app/views/discover/results/tags.tsx
index 0c5cca068c1a8c..81c43f94161245 100644
--- a/static/app/views/discover/results/tags.tsx
+++ b/static/app/views/discover/results/tags.tsx
@@ -19,7 +19,7 @@ import {Placeholder} from 'sentry/components/placeholder';
import {IconWarning} from 'sentry/icons';
import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {isAPIPayloadSimilar} from 'sentry/utils/discover/eventView';
import {parseLinkHeader} from 'sentry/utils/parseLinkHeader';
import type {UseApiQueryResult} from 'sentry/utils/queryClient';
diff --git a/static/app/views/discover/savedQuery/datasetSelectorTabs.spec.tsx b/static/app/views/discover/savedQuery/datasetSelectorTabs.spec.tsx
index 1ec7d3473d9da3..0a2d298a17ee62 100644
--- a/static/app/views/discover/savedQuery/datasetSelectorTabs.spec.tsx
+++ b/static/app/views/discover/savedQuery/datasetSelectorTabs.spec.tsx
@@ -2,7 +2,7 @@ import {OrganizationFixture} from 'sentry-fixture/organization';
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
-import EventView, {type EventViewOptions} from 'sentry/utils/discover/eventView';
+import {EventView, type EventViewOptions} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {DatasetSelectorTabs} from 'sentry/views/discover/savedQuery/datasetSelectorTabs';
diff --git a/static/app/views/discover/savedQuery/datasetSelectorTabs.tsx b/static/app/views/discover/savedQuery/datasetSelectorTabs.tsx
index 295064614c5241..82bd9435ac209d 100644
--- a/static/app/views/discover/savedQuery/datasetSelectorTabs.tsx
+++ b/static/app/views/discover/savedQuery/datasetSelectorTabs.tsx
@@ -3,7 +3,7 @@ import {TabList} from '@sentry/scraps/tabs';
import * as Layout from 'sentry/components/layouts/thirds';
import {t} from 'sentry/locale';
import type {SavedQuery} from 'sentry/types/organization';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {
ERROR_ONLY_FIELDS,
explodeField,
diff --git a/static/app/views/discover/savedQuery/index.spec.tsx b/static/app/views/discover/savedQuery/index.spec.tsx
index ff138394ce9456..0fc22fba0417e6 100644
--- a/static/app/views/discover/savedQuery/index.spec.tsx
+++ b/static/app/views/discover/savedQuery/index.spec.tsx
@@ -5,7 +5,7 @@ import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrar
import {openAddToDashboardModal} from 'sentry/actionCreators/modal';
import type {NewQuery, Organization, SavedQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DisplayModes, SavedQueryDatasets} from 'sentry/utils/discover/types';
import {getAllViews} from 'sentry/views/discover/results/data';
import SavedQueryButtonGroup from 'sentry/views/discover/savedQuery';
diff --git a/static/app/views/discover/savedQuery/index.tsx b/static/app/views/discover/savedQuery/index.tsx
index e40d19ddb807d2..50c316ae9f1d74 100644
--- a/static/app/views/discover/savedQuery/index.tsx
+++ b/static/app/views/discover/savedQuery/index.tsx
@@ -28,7 +28,7 @@ import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
import {browserHistory} from 'sentry/utils/browserHistory';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {getDiscoverQueriesUrl} from 'sentry/utils/discover/urls';
import {normalizeUrl} from 'sentry/utils/url/normalizeUrl';
diff --git a/static/app/views/discover/savedQuery/utils.spec.tsx b/static/app/views/discover/savedQuery/utils.spec.tsx
index 895434e195dc9a..eb7ba0f7e0c4e5 100644
--- a/static/app/views/discover/savedQuery/utils.spec.tsx
+++ b/static/app/views/discover/savedQuery/utils.spec.tsx
@@ -1,6 +1,6 @@
import {OrganizationFixture} from 'sentry-fixture/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {getAllViews} from 'sentry/views/discover/results/data';
import {
handleCreateQuery,
diff --git a/static/app/views/discover/savedQuery/utils.tsx b/static/app/views/discover/savedQuery/utils.tsx
index 45735c53ba382a..c2970dc4fd2ee6 100644
--- a/static/app/views/discover/savedQuery/utils.tsx
+++ b/static/app/views/discover/savedQuery/utils.tsx
@@ -17,7 +17,7 @@ import {t, tct} from 'sentry/locale';
import type {NewQuery, Organization, SavedQuery} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
import type {SaveQueryEventParameters} from 'sentry/utils/analytics/discoverAnalyticsEvents';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {
DiscoverDatasets,
DisplayModes,
diff --git a/static/app/views/discover/table/cellAction.spec.tsx b/static/app/views/discover/table/cellAction.spec.tsx
index 5872c60ea38196..6da1a1162e44d0 100644
--- a/static/app/views/discover/table/cellAction.spec.tsx
+++ b/static/app/views/discover/table/cellAction.spec.tsx
@@ -3,7 +3,7 @@ import {LocationFixture} from 'sentry-fixture/locationFixture';
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import type {TableDataRow} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {Actions, CellAction, updateQuery} from 'sentry/views/discover/table/cellAction';
import type {TableColumn} from 'sentry/views/discover/table/types';
diff --git a/static/app/views/discover/table/index.tsx b/static/app/views/discover/table/index.tsx
index f57763abb4109c..72c4d2db91144e 100644
--- a/static/app/views/discover/table/index.tsx
+++ b/static/app/views/discover/table/index.tsx
@@ -4,7 +4,7 @@ import type {Location} from 'history';
import type {EventQuery} from 'sentry/actionCreators/events';
import type {Client} from 'sentry/api';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import type {CursorHandler} from 'sentry/components/pagination';
import {Pagination} from 'sentry/components/pagination';
import {t} from 'sentry/locale';
@@ -12,8 +12,7 @@ import type {Organization} from 'sentry/types/organization';
import {metric, trackAnalytics} from 'sentry/utils/analytics';
import {CustomMeasurementsContext} from 'sentry/utils/customMeasurements/customMeasurementsContext';
import type {TableData} from 'sentry/utils/discover/discoverQuery';
-import type {LocationQuery} from 'sentry/utils/discover/eventView';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView, LocationQuery} from 'sentry/utils/discover/eventView';
import {isAPIPayloadSimilar, isFieldsSimilar} from 'sentry/utils/discover/eventView';
import {SPAN_OP_BREAKDOWN_FIELDS} from 'sentry/utils/discover/fields';
import type {DiscoverDatasets, SavedQueryDatasets} from 'sentry/utils/discover/types';
diff --git a/static/app/views/discover/table/quickContext/actionDropdown.spec.tsx b/static/app/views/discover/table/quickContext/actionDropdown.spec.tsx
index 9a0d2dd3072503..b5e02e3e7a5228 100644
--- a/static/app/views/discover/table/quickContext/actionDropdown.spec.tsx
+++ b/static/app/views/discover/table/quickContext/actionDropdown.spec.tsx
@@ -5,7 +5,7 @@ import {OrganizationFixture} from 'sentry-fixture/organization';
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import type {EventData} from 'sentry/utils/discover/eventView';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {ActionDropDown, ContextValueType} from './actionDropdown';
diff --git a/static/app/views/discover/table/quickContext/actionDropdown.tsx b/static/app/views/discover/table/quickContext/actionDropdown.tsx
index eb9482ebbbae2e..88bda0211f8ee4 100644
--- a/static/app/views/discover/table/quickContext/actionDropdown.tsx
+++ b/static/app/views/discover/table/quickContext/actionDropdown.tsx
@@ -10,8 +10,7 @@ import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
import {toArray} from 'sentry/utils/array/toArray';
-import type {EventData} from 'sentry/utils/discover/eventView';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventData, EventView} from 'sentry/utils/discover/eventView';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useNavigate} from 'sentry/utils/useNavigate';
import {addToFilter, excludeFromFilter} from 'sentry/views/discover/table/cellAction';
diff --git a/static/app/views/discover/table/quickContext/eventContext.spec.tsx b/static/app/views/discover/table/quickContext/eventContext.spec.tsx
index 36865dec6b8dd4..91bc98288a71dd 100644
--- a/static/app/views/discover/table/quickContext/eventContext.spec.tsx
+++ b/static/app/views/discover/table/quickContext/eventContext.spec.tsx
@@ -14,8 +14,7 @@ import type {
Frame,
} from 'sentry/types/event';
import {EntryType, EventOrGroupType} from 'sentry/types/event';
-import type {EventData} from 'sentry/utils/discover/eventView';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventData, EventView} from 'sentry/utils/discover/eventView';
import {EventContext} from './eventContext';
diff --git a/static/app/views/discover/table/quickContext/eventContext.tsx b/static/app/views/discover/table/quickContext/eventContext.tsx
index 6d3ca6acbc02d1..ecca549e9766d3 100644
--- a/static/app/views/discover/table/quickContext/eventContext.tsx
+++ b/static/app/views/discover/table/quickContext/eventContext.tsx
@@ -11,7 +11,7 @@ import type {Event, EventTransaction} from 'sentry/types/event';
import type {Project} from 'sentry/types/project';
import {trackAnalytics} from 'sentry/utils/analytics';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {getDuration} from 'sentry/utils/duration/getDuration';
import {useApiQuery} from 'sentry/utils/queryClient';
diff --git a/static/app/views/discover/table/quickContext/quickContextHovercard.spec.tsx b/static/app/views/discover/table/quickContext/quickContextHovercard.spec.tsx
index 8d79882c4d7e60..12db39d7c6e77f 100644
--- a/static/app/views/discover/table/quickContext/quickContextHovercard.spec.tsx
+++ b/static/app/views/discover/table/quickContext/quickContextHovercard.spec.tsx
@@ -7,8 +7,7 @@ import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import {ConfigStore} from 'sentry/stores/configStore';
import {EventOrGroupType} from 'sentry/types/event';
import {ReleaseStatus} from 'sentry/types/release';
-import type {EventData} from 'sentry/utils/discover/eventView';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventData, EventView} from 'sentry/utils/discover/eventView';
import {QuickContextHoverWrapper} from './quickContextWrapper';
import {defaultRow, mockedCommit, mockedUser1, mockedUser2} from './testUtils';
diff --git a/static/app/views/discover/table/quickContext/quickContextHovercard.tsx b/static/app/views/discover/table/quickContext/quickContextHovercard.tsx
index 1e35e9cbe66c7a..d6482b9c4e7f14 100644
--- a/static/app/views/discover/table/quickContext/quickContextHovercard.tsx
+++ b/static/app/views/discover/table/quickContext/quickContextHovercard.tsx
@@ -11,8 +11,7 @@ import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type {EventData} from 'sentry/utils/discover/eventView';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventData, EventView} from 'sentry/utils/discover/eventView';
import {getShortEventId} from 'sentry/utils/events';
import {useLocation} from 'sentry/utils/useLocation';
diff --git a/static/app/views/discover/table/tableActions.tsx b/static/app/views/discover/table/tableActions.tsx
index 5ecb56b942b4b6..8b0f6c315994d8 100644
--- a/static/app/views/discover/table/tableActions.tsx
+++ b/static/app/views/discover/table/tableActions.tsx
@@ -13,7 +13,7 @@ import {t} from 'sentry/locale';
import type {OrganizationSummary} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
import type {TableData} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {SavedQueryDatasets} from 'sentry/utils/discover/types';
import {downloadAsCsv} from 'sentry/views/discover/utils';
diff --git a/static/app/views/discover/table/tableView.spec.tsx b/static/app/views/discover/table/tableView.spec.tsx
index 22957abd97fc42..bf93622896bdbd 100644
--- a/static/app/views/discover/table/tableView.spec.tsx
+++ b/static/app/views/discover/table/tableView.spec.tsx
@@ -14,7 +14,7 @@ import {
import {ProjectsStore} from 'sentry/stores/projectsStore';
import {TagStore} from 'sentry/stores/tagStore';
import type {TableData} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {SavedQueryDatasets} from 'sentry/utils/discover/types';
import {TableView} from 'sentry/views/discover/table/tableView';
diff --git a/static/app/views/discover/table/tableView.tsx b/static/app/views/discover/table/tableView.tsx
index 3593915baceeb7..3b579ccaac2f3d 100644
--- a/static/app/views/discover/table/tableView.tsx
+++ b/static/app/views/discover/table/tableView.tsx
@@ -20,7 +20,7 @@ import {trackAnalytics} from 'sentry/utils/analytics';
import type {CustomMeasurementCollection} from 'sentry/utils/customMeasurements/customMeasurements';
import {getTimeStampFromTableDateField} from 'sentry/utils/dates';
import type {TableData, TableDataRow} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {isFieldSortable} from 'sentry/utils/discover/eventView';
import {
DURATION_UNITS,
diff --git a/static/app/views/discover/utils.spec.tsx b/static/app/views/discover/utils.spec.tsx
index e0acb17da82739..8721f9ca337de0 100644
--- a/static/app/views/discover/utils.spec.tsx
+++ b/static/app/views/discover/utils.spec.tsx
@@ -9,7 +9,7 @@ import {openAddToDashboardModal} from 'sentry/actionCreators/modal';
import {COL_WIDTH_UNDEFINED} from 'sentry/components/tables/gridEditable';
import type {Organization} from 'sentry/types/organization';
import type {EventViewOptions} from 'sentry/utils/discover/eventView';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DisplayModes} from 'sentry/utils/discover/types';
import {
DashboardWidgetSource,
diff --git a/static/app/views/discover/utils.tsx b/static/app/views/discover/utils.tsx
index 80b38d847e95f3..d7cf4a52c7adb8 100644
--- a/static/app/views/discover/utils.tsx
+++ b/static/app/views/discover/utils.tsx
@@ -17,8 +17,7 @@ import {defined} from 'sentry/utils';
import {toArray} from 'sentry/utils/array/toArray';
import {getUtcDateString} from 'sentry/utils/dates';
import type {TableDataRow} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
-import type {EventData, MetaType} from 'sentry/utils/discover/eventView';
+import type {EventData, EventView, MetaType} from 'sentry/utils/discover/eventView';
import type {
Aggregation,
Column,
diff --git a/static/app/views/explore/components/attributeBreakdowns/attributeDistributionContent.tsx b/static/app/views/explore/components/attributeBreakdowns/attributeDistributionContent.tsx
index 603e0af87cd55b..b4b3f37fdc8eb1 100644
--- a/static/app/views/explore/components/attributeBreakdowns/attributeDistributionContent.tsx
+++ b/static/app/views/explore/components/attributeBreakdowns/attributeDistributionContent.tsx
@@ -11,7 +11,7 @@ import {IconClose} from 'sentry/icons/iconClose';
import {t} from 'sentry/locale';
import type {NewQuery} from 'sentry/types/organization';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {parseLinkHeader} from 'sentry/utils/parseLinkHeader';
import {useApiQuery} from 'sentry/utils/queryClient';
import {useQueryParamState} from 'sentry/utils/url/useQueryParamState';
diff --git a/static/app/views/explore/components/traceItemAttributes/attributesTreeValue.tsx b/static/app/views/explore/components/traceItemAttributes/attributesTreeValue.tsx
index 8b8be561fb0f6e..f35e567e1980ae 100644
--- a/static/app/views/explore/components/traceItemAttributes/attributesTreeValue.tsx
+++ b/static/app/views/explore/components/traceItemAttributes/attributesTreeValue.tsx
@@ -2,7 +2,7 @@ import {type Theme} from '@emotion/react';
import styled from '@emotion/styled';
import {openNavigateToExternalLinkModal} from 'sentry/actionCreators/modal';
-import ExternalLink from 'sentry/components/links/externalLink';
+import {ExternalLink} from 'sentry/components/links/externalLink';
import {type RenderFunctionBaggage} from 'sentry/utils/discover/fieldRenderers';
import {isUrl} from 'sentry/utils/string/isUrl';
import {AnnotatedAttributeTooltip} from 'sentry/views/explore/components/annotatedAttributeTooltip';
diff --git a/static/app/views/explore/hooks/useAddToDashboard.tsx b/static/app/views/explore/hooks/useAddToDashboard.tsx
index e6a4bc778ee5bc..4f84d97e0bd934 100644
--- a/static/app/views/explore/hooks/useAddToDashboard.tsx
+++ b/static/app/views/explore/hooks/useAddToDashboard.tsx
@@ -2,7 +2,7 @@ import {useCallback} from 'react';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import type {NewQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useLocation} from 'sentry/utils/useLocation';
import {useOrganization} from 'sentry/utils/useOrganization';
diff --git a/static/app/views/explore/hooks/useExploreAggregatesTable.tsx b/static/app/views/explore/hooks/useExploreAggregatesTable.tsx
index bbe8b97115aea3..f27c95c1d63d42 100644
--- a/static/app/views/explore/hooks/useExploreAggregatesTable.tsx
+++ b/static/app/views/explore/hooks/useExploreAggregatesTable.tsx
@@ -3,7 +3,7 @@ import {useCallback, useMemo} from 'react';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import type {NewQuery} from 'sentry/types/organization';
import {defined} from 'sentry/utils';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {isGroupBy} from 'sentry/views/explore/contexts/pageParamsContext/aggregateFields';
import {formatSort} from 'sentry/views/explore/contexts/pageParamsContext/sortBys';
import type {RPCQueryExtras} from 'sentry/views/explore/hooks/useProgressiveQuery';
diff --git a/static/app/views/explore/hooks/useExploreSpansTable.tsx b/static/app/views/explore/hooks/useExploreSpansTable.tsx
index 267c10876b36b0..f14d6f19311652 100644
--- a/static/app/views/explore/hooks/useExploreSpansTable.tsx
+++ b/static/app/views/explore/hooks/useExploreSpansTable.tsx
@@ -3,7 +3,7 @@ import {useCallback, useMemo} from 'react';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import type {NewQuery} from 'sentry/types/organization';
import {defined} from 'sentry/utils';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {
useProgressiveQuery,
type RPCQueryExtras,
diff --git a/static/app/views/explore/logs/logsGraph.tsx b/static/app/views/explore/logs/logsGraph.tsx
index 42fa0b67a91af6..f45cdc78d1b4d7 100644
--- a/static/app/views/explore/logs/logsGraph.tsx
+++ b/static/app/views/explore/logs/logsGraph.tsx
@@ -12,7 +12,7 @@ import {t} from 'sentry/locale';
import type {NewQuery} from 'sentry/types/organization';
import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {useChartInterval} from 'sentry/utils/useChartInterval';
import {useLocation} from 'sentry/utils/useLocation';
diff --git a/static/app/views/explore/logs/useSaveAsItems.tsx b/static/app/views/explore/logs/useSaveAsItems.tsx
index 03f5f01a24afdd..489b76644be376 100644
--- a/static/app/views/explore/logs/useSaveAsItems.tsx
+++ b/static/app/views/explore/logs/useSaveAsItems.tsx
@@ -14,7 +14,7 @@ import {t} from 'sentry/locale';
import type {NewQuery} from 'sentry/types/organization';
import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import type {Sort} from 'sentry/utils/discover/fields';
import {parseFunction, prettifyParsedFunction} from 'sentry/utils/discover/fields';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
diff --git a/static/app/views/explore/metrics/hooks/useAddMetricToDashboard.tsx b/static/app/views/explore/metrics/hooks/useAddMetricToDashboard.tsx
index bb8059203156f9..4dc0361c00e61a 100644
--- a/static/app/views/explore/metrics/hooks/useAddMetricToDashboard.tsx
+++ b/static/app/views/explore/metrics/hooks/useAddMetricToDashboard.tsx
@@ -2,7 +2,7 @@ import {useCallback} from 'react';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import type {NewQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useLocation} from 'sentry/utils/useLocation';
diff --git a/static/app/views/explore/metrics/hooks/useMetricAggregatesTable.tsx b/static/app/views/explore/metrics/hooks/useMetricAggregatesTable.tsx
index 41a64d26795828..075b823f7c2171 100644
--- a/static/app/views/explore/metrics/hooks/useMetricAggregatesTable.tsx
+++ b/static/app/views/explore/metrics/hooks/useMetricAggregatesTable.tsx
@@ -3,7 +3,7 @@ import {useCallback, useMemo} from 'react';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import type {NewQuery} from 'sentry/types/organization';
import {defined} from 'sentry/utils';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {formatSort} from 'sentry/views/explore/contexts/pageParamsContext/sortBys';
import {
diff --git a/static/app/views/explore/metrics/hooks/useMetricSamplesTable.tsx b/static/app/views/explore/metrics/hooks/useMetricSamplesTable.tsx
index 58220b1bc7cf5f..8acee18b23bca4 100644
--- a/static/app/views/explore/metrics/hooks/useMetricSamplesTable.tsx
+++ b/static/app/views/explore/metrics/hooks/useMetricSamplesTable.tsx
@@ -4,8 +4,7 @@ import moment from 'moment-timezone';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import {defined} from 'sentry/utils';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
-import type EventView from 'sentry/utils/discover/eventView';
-import type {EventsMetaType} from 'sentry/utils/discover/eventView';
+import type {EventsMetaType, EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {intervalToMilliseconds} from 'sentry/utils/duration/intervalToMilliseconds';
import {useApiQuery, type ApiQueryKey} from 'sentry/utils/queryClient';
diff --git a/static/app/views/explore/metrics/hooks/useTraceTelemetry.tsx b/static/app/views/explore/metrics/hooks/useTraceTelemetry.tsx
index 33132d07a87a57..6dfa500ed5d4f0 100644
--- a/static/app/views/explore/metrics/hooks/useTraceTelemetry.tsx
+++ b/static/app/views/explore/metrics/hooks/useTraceTelemetry.tsx
@@ -4,7 +4,7 @@ import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import {MutableSearch} from 'sentry/components/searchSyntax/mutableSearch';
import type {NewQuery} from 'sentry/types/organization';
import {useDiscoverQuery, type TableDataRow} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {useLocation} from 'sentry/utils/useLocation';
import {useOrganization} from 'sentry/utils/useOrganization';
diff --git a/static/app/views/explore/multiQueryMode/hooks/useAddCompareQueryToDashboard.tsx b/static/app/views/explore/multiQueryMode/hooks/useAddCompareQueryToDashboard.tsx
index 250dce6aca2e2d..48be2adb30531b 100644
--- a/static/app/views/explore/multiQueryMode/hooks/useAddCompareQueryToDashboard.tsx
+++ b/static/app/views/explore/multiQueryMode/hooks/useAddCompareQueryToDashboard.tsx
@@ -2,7 +2,7 @@ import {useCallback} from 'react';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import type {NewQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useLocation} from 'sentry/utils/useLocation';
diff --git a/static/app/views/explore/multiQueryMode/hooks/useMultiQueryTable.tsx b/static/app/views/explore/multiQueryMode/hooks/useMultiQueryTable.tsx
index 6e67ab2793ddff..c96dda14f66b0f 100644
--- a/static/app/views/explore/multiQueryMode/hooks/useMultiQueryTable.tsx
+++ b/static/app/views/explore/multiQueryMode/hooks/useMultiQueryTable.tsx
@@ -3,7 +3,7 @@ import {useCallback, useMemo} from 'react';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import type {NewQuery} from 'sentry/types/organization';
import {defined} from 'sentry/utils';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import type {Sort} from 'sentry/utils/discover/fields';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {formatSort} from 'sentry/views/explore/contexts/pageParamsContext/sortBys';
diff --git a/static/app/views/explore/tables/fieldRenderer.spec.tsx b/static/app/views/explore/tables/fieldRenderer.spec.tsx
index 3e1794ca4952b7..6ca21d0d7df7f5 100644
--- a/static/app/views/explore/tables/fieldRenderer.spec.tsx
+++ b/static/app/views/explore/tables/fieldRenderer.spec.tsx
@@ -7,7 +7,7 @@ import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import {resetMockDate, setMockDate} from 'sentry-test/utils';
import {ProjectsStore} from 'sentry/stores/projectsStore';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {SpansQueryParamsProvider} from 'sentry/views/explore/spans/spansQueryParamsProvider';
import {FieldRenderer} from 'sentry/views/explore/tables/fieldRenderer';
diff --git a/static/app/views/explore/tables/fieldRenderer.tsx b/static/app/views/explore/tables/fieldRenderer.tsx
index bb4c2db16c70d1..67294bb6344c9a 100644
--- a/static/app/views/explore/tables/fieldRenderer.tsx
+++ b/static/app/views/explore/tables/fieldRenderer.tsx
@@ -15,7 +15,7 @@ import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
import type {TableDataRow} from 'sentry/utils/discover/discoverQuery';
import type {EventData, MetaType} from 'sentry/utils/discover/eventView';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {getFieldRenderer, nullableValue} from 'sentry/utils/discover/fieldRenderers';
import {Container} from 'sentry/utils/discover/styles';
import {generateLinkToEventInTraceView} from 'sentry/utils/discover/urls';
diff --git a/static/app/views/explore/tables/tracesTable/spansTable.tsx b/static/app/views/explore/tables/tracesTable/spansTable.tsx
index 95f91f7b9e934d..2d00cd6337d68b 100644
--- a/static/app/views/explore/tables/tracesTable/spansTable.tsx
+++ b/static/app/views/explore/tables/tracesTable/spansTable.tsx
@@ -12,7 +12,7 @@ import {t, tct} from 'sentry/locale';
import type {NewQuery, Organization} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
import {getUtcDateString} from 'sentry/utils/dates';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useOrganization} from 'sentry/utils/useOrganization';
import {useQueryParamsQuery} from 'sentry/views/explore//queryParams/context';
diff --git a/static/app/views/feedback/feedbackListPage.tsx b/static/app/views/feedback/feedbackListPage.tsx
index 9b55637e128636..7ec776ba920d7c 100644
--- a/static/app/views/feedback/feedbackListPage.tsx
+++ b/static/app/views/feedback/feedbackListPage.tsx
@@ -6,7 +6,7 @@ import {Button, LinkButton} from '@sentry/scraps/button';
import {Flex, Stack} from '@sentry/scraps/layout';
import {AnalyticsArea} from 'sentry/components/analyticsArea';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {FeedbackFilters} from 'sentry/components/feedback/feedbackFilters';
import {FeedbackItemLoader} from 'sentry/components/feedback/feedbackItem/feedbackItemLoader';
import {FeedbackSearch} from 'sentry/components/feedback/feedbackSearch';
diff --git a/static/app/views/insights/agentModels/views/modelsLandingPage.tsx b/static/app/views/insights/agentModels/views/modelsLandingPage.tsx
index 4085c69dabef5a..0b3162f5cd7952 100644
--- a/static/app/views/insights/agentModels/views/modelsLandingPage.tsx
+++ b/static/app/views/insights/agentModels/views/modelsLandingPage.tsx
@@ -2,7 +2,7 @@ import {Fragment} from 'react';
import {Flex} from '@sentry/scraps/layout';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import * as Layout from 'sentry/components/layouts/thirds';
import type {DatePageFilterProps} from 'sentry/components/pageFilters/date/datePageFilter';
import {DatePageFilter} from 'sentry/components/pageFilters/date/datePageFilter';
diff --git a/static/app/views/insights/common/components/chart.tsx b/static/app/views/insights/common/components/chart.tsx
index 6097fbcdb2dd0e..1735a313123bd4 100644
--- a/static/app/views/insights/common/components/chart.tsx
+++ b/static/app/views/insights/common/components/chart.tsx
@@ -25,7 +25,7 @@ import {ErrorPanel} from 'sentry/components/charts/errorPanel';
import ReleaseSeries from 'sentry/components/charts/releaseSeries';
import {LineSeries} from 'sentry/components/charts/series/lineSeries';
import {ScatterSeries} from 'sentry/components/charts/series/scatterSeries';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
import {isChartHovered} from 'sentry/components/charts/utils';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
diff --git a/static/app/views/insights/common/queries/getSeriesEventView.tsx b/static/app/views/insights/common/queries/getSeriesEventView.tsx
index 20e10696820639..979d8f6c918767 100644
--- a/static/app/views/insights/common/queries/getSeriesEventView.tsx
+++ b/static/app/views/insights/common/queries/getSeriesEventView.tsx
@@ -1,5 +1,5 @@
import type {PageFilters} from 'sentry/types/core';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {getIntervalForTimeSeriesQuery} from 'sentry/utils/timeSeries/getIntervalForTimeSeriesQuery';
import type {MutableSearch} from 'sentry/utils/tokenizeSearch';
diff --git a/static/app/views/insights/common/queries/useDiscover.ts b/static/app/views/insights/common/queries/useDiscover.ts
index c3f50f05ff225d..dd4f1038628bb3 100644
--- a/static/app/views/insights/common/queries/useDiscover.ts
+++ b/static/app/views/insights/common/queries/useDiscover.ts
@@ -1,6 +1,6 @@
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import type {PageFilters} from 'sentry/types/core';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import type {Sort} from 'sentry/utils/discover/fields';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import type {MutableSearch} from 'sentry/utils/tokenizeSearch';
diff --git a/static/app/views/insights/common/queries/useReleases.tsx b/static/app/views/insights/common/queries/useReleases.tsx
index 7a04de01e6a371..a8ccb5c14a4444 100644
--- a/static/app/views/insights/common/queries/useReleases.tsx
+++ b/static/app/views/insights/common/queries/useReleases.tsx
@@ -7,7 +7,7 @@ import type {Release} from 'sentry/types/release';
import {parseQueryKey} from 'sentry/utils/api/apiQueryKey';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
import type {TableData} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import type {ApiQueryKey} from 'sentry/utils/queryClient';
import {useApiQuery, useQueries} from 'sentry/utils/queryClient';
diff --git a/static/app/views/insights/common/queries/useSpansQuery.tsx b/static/app/views/insights/common/queries/useSpansQuery.tsx
index 84e3d8785fe36e..63444c5ee3600c 100644
--- a/static/app/views/insights/common/queries/useSpansQuery.tsx
+++ b/static/app/views/insights/common/queries/useSpansQuery.tsx
@@ -5,8 +5,7 @@ import type {CaseInsensitive} from 'sentry/components/searchQueryBuilder/hooks';
import {defined} from 'sentry/utils';
import type {TableData} from 'sentry/utils/discover/discoverQuery';
import {useDiscoverQuery} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
-import type {EventsMetaType, MetaType} from 'sentry/utils/discover/eventView';
+import type {EventsMetaType, EventView, MetaType} from 'sentry/utils/discover/eventView';
import {encodeSort} from 'sentry/utils/discover/eventView';
import type {DiscoverQueryProps} from 'sentry/utils/discover/genericDiscoverQuery';
import {useGenericDiscoverQuery} from 'sentry/utils/discover/genericDiscoverQuery';
diff --git a/static/app/views/insights/common/utils/trackResponse.tsx b/static/app/views/insights/common/utils/trackResponse.tsx
index d24e23b083dbaa..70b0d92c8e9803 100644
--- a/static/app/views/insights/common/utils/trackResponse.tsx
+++ b/static/app/views/insights/common/utils/trackResponse.tsx
@@ -1,7 +1,7 @@
import {useEffect, useState} from 'react';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {useOrganization} from 'sentry/utils/useOrganization';
export function TrackResponse(
diff --git a/static/app/views/insights/common/utils/useAddToSpanDashboard.ts b/static/app/views/insights/common/utils/useAddToSpanDashboard.ts
index c76d9295fafcc7..106bf81662df04 100644
--- a/static/app/views/insights/common/utils/useAddToSpanDashboard.ts
+++ b/static/app/views/insights/common/utils/useAddToSpanDashboard.ts
@@ -2,7 +2,7 @@ import {useCallback} from 'react';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import type {NewQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import type {Sort} from 'sentry/utils/discover/fields';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {getIntervalForTimeSeriesQuery} from 'sentry/utils/timeSeries/getIntervalForTimeSeriesQuery';
diff --git a/static/app/views/insights/mobile/appStarts/components/eventSamples.tsx b/static/app/views/insights/mobile/appStarts/components/eventSamples.tsx
index 3da742837ec11f..9fc340af948879 100644
--- a/static/app/views/insights/mobile/appStarts/components/eventSamples.tsx
+++ b/static/app/views/insights/mobile/appStarts/components/eventSamples.tsx
@@ -1,7 +1,7 @@
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import {t} from 'sentry/locale';
import type {NewQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import type {Sort} from 'sentry/utils/discover/fields';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {decodeScalar, decodeSorts} from 'sentry/utils/queryString';
diff --git a/static/app/views/insights/mobile/appStarts/components/samples.tsx b/static/app/views/insights/mobile/appStarts/components/samples.tsx
index c5c98b8fbcdeab..0d4a2a2219ece7 100644
--- a/static/app/views/insights/mobile/appStarts/components/samples.tsx
+++ b/static/app/views/insights/mobile/appStarts/components/samples.tsx
@@ -3,7 +3,7 @@ import {useMemo, useState} from 'react';
import {Flex} from '@sentry/scraps/layout';
import {SegmentedControl} from '@sentry/scraps/segmentedControl';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {t} from 'sentry/locale';
import {trackAnalytics} from 'sentry/utils/analytics';
import {useOrganization} from 'sentry/utils/useOrganization';
diff --git a/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx b/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx
index 6c7b8a0b2a0c94..2b15022a4022e5 100644
--- a/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx
+++ b/static/app/views/insights/mobile/appStarts/views/screenSummaryPage.tsx
@@ -2,7 +2,7 @@ import {Fragment, useEffect} from 'react';
import styled from '@emotion/styled';
import omit from 'lodash/omit';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {t} from 'sentry/locale';
import {defined} from 'sentry/utils';
import {DurationUnit} from 'sentry/utils/discover/fields';
diff --git a/static/app/views/insights/mobile/common/components/tables/samplesTables.tsx b/static/app/views/insights/mobile/common/components/tables/samplesTables.tsx
index 64a3fd921fe148..84f0151ccfbaf2 100644
--- a/static/app/views/insights/mobile/common/components/tables/samplesTables.tsx
+++ b/static/app/views/insights/mobile/common/components/tables/samplesTables.tsx
@@ -3,7 +3,7 @@ import {useMemo, useState} from 'react';
import {Flex} from '@sentry/scraps/layout';
import {SegmentedControl} from '@sentry/scraps/segmentedControl';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {t} from 'sentry/locale';
import {useReleaseSelection} from 'sentry/views/insights/common/queries/useReleases';
import {SubregionSelector} from 'sentry/views/insights/common/views/spans/selectors/subregionSelector';
diff --git a/static/app/views/insights/mobile/common/components/tables/screensTable.spec.tsx b/static/app/views/insights/mobile/common/components/tables/screensTable.spec.tsx
index 1343f8fbdf9869..188434fc5bb8a0 100644
--- a/static/app/views/insights/mobile/common/components/tables/screensTable.spec.tsx
+++ b/static/app/views/insights/mobile/common/components/tables/screensTable.spec.tsx
@@ -1,6 +1,6 @@
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {ScreensTable} from 'sentry/views/insights/mobile/common/components/tables/screensTable';
diff --git a/static/app/views/insights/mobile/common/components/tables/screensTable.tsx b/static/app/views/insights/mobile/common/components/tables/screensTable.tsx
index 30c48dfca14552..632df623ea7f08 100644
--- a/static/app/views/insights/mobile/common/components/tables/screensTable.tsx
+++ b/static/app/views/insights/mobile/common/components/tables/screensTable.tsx
@@ -16,7 +16,7 @@ import {useQueryBasedColumnResize} from 'sentry/components/tables/gridEditable/u
import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
import type {TableDataRow} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {isFieldSortable, type MetaType} from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import {fieldAlignment} from 'sentry/utils/discover/fields';
diff --git a/static/app/views/insights/mobile/screenload/components/eventSamples.tsx b/static/app/views/insights/mobile/screenload/components/eventSamples.tsx
index 09c57ff99e4b55..f04a76b545c85e 100644
--- a/static/app/views/insights/mobile/screenload/components/eventSamples.tsx
+++ b/static/app/views/insights/mobile/screenload/components/eventSamples.tsx
@@ -3,7 +3,7 @@ import {useMemo} from 'react';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import {t} from 'sentry/locale';
import type {NewQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import type {Sort} from 'sentry/utils/discover/fields';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {decodeList, decodeScalar, decodeSorts} from 'sentry/utils/queryString';
diff --git a/static/app/views/insights/mobile/screenload/components/tables/eventSamplesTable.spec.tsx b/static/app/views/insights/mobile/screenload/components/tables/eventSamplesTable.spec.tsx
index 08ee84bcb4b80d..8c80fa2132c569 100644
--- a/static/app/views/insights/mobile/screenload/components/tables/eventSamplesTable.spec.tsx
+++ b/static/app/views/insights/mobile/screenload/components/tables/eventSamplesTable.spec.tsx
@@ -3,7 +3,7 @@ import {LocationFixture} from 'sentry-fixture/locationFixture';
import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
import type {NewQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {EventSamplesTable} from 'sentry/views/insights/mobile/screenload/components/tables/eventSamplesTable';
describe('EventSamplesTable', () => {
diff --git a/static/app/views/insights/mobile/screenload/components/tables/eventSamplesTable.tsx b/static/app/views/insights/mobile/screenload/components/tables/eventSamplesTable.tsx
index 1c03bf9ce949d4..f51c2dc3f1891f 100644
--- a/static/app/views/insights/mobile/screenload/components/tables/eventSamplesTable.tsx
+++ b/static/app/views/insights/mobile/screenload/components/tables/eventSamplesTable.tsx
@@ -19,8 +19,7 @@ import {IconProfiling} from 'sentry/icons/iconProfiling';
import {t} from 'sentry/locale';
import {defined} from 'sentry/utils';
import type {TableData, TableDataRow} from 'sentry/utils/discover/discoverQuery';
-import type {MetaType} from 'sentry/utils/discover/eventView';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView, MetaType} from 'sentry/utils/discover/eventView';
import {isFieldSortable} from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import type {Sort} from 'sentry/utils/discover/fields';
diff --git a/static/app/views/insights/mobile/screenload/views/screenLoadSpansPage.tsx b/static/app/views/insights/mobile/screenload/views/screenLoadSpansPage.tsx
index 910cf0d013f00c..33966ade958339 100644
--- a/static/app/views/insights/mobile/screenload/views/screenLoadSpansPage.tsx
+++ b/static/app/views/insights/mobile/screenload/views/screenLoadSpansPage.tsx
@@ -5,7 +5,7 @@ import omit from 'lodash/omit';
import {Flex} from '@sentry/scraps/layout';
import {SegmentedControl} from '@sentry/scraps/segmentedControl';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {t} from 'sentry/locale';
import {DurationUnit} from 'sentry/utils/discover/fields';
import {useLocation} from 'sentry/utils/useLocation';
diff --git a/static/app/views/insights/mobile/screens/components/screensOverview.tsx b/static/app/views/insights/mobile/screens/components/screensOverview.tsx
index 400946b3e25c1a..99ffb4c6bfbee8 100644
--- a/static/app/views/insights/mobile/screens/components/screensOverview.tsx
+++ b/static/app/views/insights/mobile/screens/components/screensOverview.tsx
@@ -6,7 +6,7 @@ import {wrapQueryInWildcards} from 'sentry/components/performance/searchBar';
import {SearchBar} from 'sentry/components/searchBar';
import {t} from 'sentry/locale';
import type {NewQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {decodeScalar, decodeSorts} from 'sentry/utils/queryString';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useLocation} from 'sentry/utils/useLocation';
diff --git a/static/app/views/insights/mobile/screens/components/screensOverviewTable.spec.tsx b/static/app/views/insights/mobile/screens/components/screensOverviewTable.spec.tsx
index 55d60b479ace83..975f35284094d6 100644
--- a/static/app/views/insights/mobile/screens/components/screensOverviewTable.spec.tsx
+++ b/static/app/views/insights/mobile/screens/components/screensOverviewTable.spec.tsx
@@ -6,7 +6,7 @@ import {ProjectFixture} from 'sentry-fixture/project';
import {render, screen} from 'sentry-test/reactTestingLibrary';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {useLocation} from 'sentry/utils/useLocation';
import {
ScreensOverviewTable,
diff --git a/static/app/views/insights/mobile/screens/components/screensOverviewTable.tsx b/static/app/views/insights/mobile/screens/components/screensOverviewTable.tsx
index 1c06b688d2eba2..19b21d9b2e67ae 100644
--- a/static/app/views/insights/mobile/screens/components/screensOverviewTable.tsx
+++ b/static/app/views/insights/mobile/screens/components/screensOverviewTable.tsx
@@ -4,8 +4,7 @@ import * as qs from 'query-string';
import {Link} from '@sentry/scraps/link';
import {t} from 'sentry/locale';
-import type EventView from 'sentry/utils/discover/eventView';
-import type {MetaType} from 'sentry/utils/discover/eventView';
+import type {EventView, MetaType} from 'sentry/utils/discover/eventView';
import {NumberContainer} from 'sentry/utils/discover/styles';
import {formatPercentage} from 'sentry/utils/number/formatPercentage';
import {normalizeUrl} from 'sentry/utils/url/normalizeUrl';
diff --git a/static/app/views/insights/mobile/screens/views/screensLandingPage.tsx b/static/app/views/insights/mobile/screens/views/screensLandingPage.tsx
index a1ac8b4a99566c..89c089c855c4ac 100644
--- a/static/app/views/insights/mobile/screens/views/screensLandingPage.tsx
+++ b/static/app/views/insights/mobile/screens/views/screensLandingPage.tsx
@@ -2,7 +2,7 @@ import {useCallback, useEffect, useState} from 'react';
import styled from '@emotion/styled';
import omit from 'lodash/omit';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import * as Layout from 'sentry/components/layouts/thirds';
import {TabbedCodeSnippet} from 'sentry/components/onboarding/gettingStartedDoc/onboardingCodeSnippet';
import {DatePageFilter} from 'sentry/components/pageFilters/date/datePageFilter';
diff --git a/static/app/views/insights/mobile/ui/components/tables/spanOperationTable.tsx b/static/app/views/insights/mobile/ui/components/tables/spanOperationTable.tsx
index fe3326caf07215..02fd1e4ba985ab 100644
--- a/static/app/views/insights/mobile/ui/components/tables/spanOperationTable.tsx
+++ b/static/app/views/insights/mobile/ui/components/tables/spanOperationTable.tsx
@@ -7,7 +7,7 @@ import {Duration} from 'sentry/components/duration';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import {t} from 'sentry/locale';
import type {NewQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {NumberContainer} from 'sentry/utils/discover/styles';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {decodeList, decodeScalar} from 'sentry/utils/queryString';
diff --git a/static/app/views/insights/pages/agents/components/modelCostWidget.tsx b/static/app/views/insights/pages/agents/components/modelCostWidget.tsx
index c6a2ee391d42ee..4adb472b617f5d 100644
--- a/static/app/views/insights/pages/agents/components/modelCostWidget.tsx
+++ b/static/app/views/insights/pages/agents/components/modelCostWidget.tsx
@@ -3,7 +3,7 @@ import {useTheme} from '@emotion/react';
import styled from '@emotion/styled';
import {openInsightChartModal} from 'sentry/actionCreators/modal';
-import ExternalLink from 'sentry/components/links/externalLink';
+import {ExternalLink} from 'sentry/components/links/externalLink';
import {t, tct} from 'sentry/locale';
import {useFetchSpanTimeSeries} from 'sentry/utils/timeSeries/useFetchEventsTimeSeries';
import {useOrganization} from 'sentry/utils/useOrganization';
diff --git a/static/app/views/insights/pages/useOverviewPageTrackAnalytics.ts b/static/app/views/insights/pages/useOverviewPageTrackAnalytics.ts
index fd51875845094d..442988ae8db1bf 100644
--- a/static/app/views/insights/pages/useOverviewPageTrackAnalytics.ts
+++ b/static/app/views/insights/pages/useOverviewPageTrackAnalytics.ts
@@ -2,7 +2,7 @@ import {useEffect} from 'react';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import {trackAnalytics} from 'sentry/utils/analytics';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {useLocation} from 'sentry/utils/useLocation';
import {useOrganization} from 'sentry/utils/useOrganization';
import {useProjects} from 'sentry/utils/useProjects';
diff --git a/static/app/views/issueDetails/activitySection.tsx b/static/app/views/issueDetails/activitySection.tsx
index 79628832950b39..ef5f526e3ff285 100644
--- a/static/app/views/issueDetails/activitySection.tsx
+++ b/static/app/views/issueDetails/activitySection.tsx
@@ -4,7 +4,7 @@ import {ActivityAuthor} from 'sentry/components/activity/author';
import {ActivityItem} from 'sentry/components/activity/item';
import {Note} from 'sentry/components/activity/note';
import {NoteInputWithStorage} from 'sentry/components/activity/note/inputWithStorage';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import type {NoteType} from 'sentry/types/alerts';
import type {Group, GroupActivity} from 'sentry/types/group';
import {GroupActivityType} from 'sentry/types/group';
diff --git a/static/app/views/issueDetails/allEventsTable.tsx b/static/app/views/issueDetails/allEventsTable.tsx
index 46ad1157259e6c..3391bc6f616fc1 100644
--- a/static/app/views/issueDetails/allEventsTable.tsx
+++ b/static/app/views/issueDetails/allEventsTable.tsx
@@ -14,7 +14,7 @@ import {IssueCategory, IssueType} from 'sentry/types/group';
import type {Organization} from 'sentry/types/organization';
import type {PlatformKey} from 'sentry/types/project';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {getConfigForIssueType} from 'sentry/utils/issueTypeConfig';
import {platformToCategory} from 'sentry/utils/platform';
diff --git a/static/app/views/issueDetails/groupEventDetails/groupEventDetailsContent.tsx b/static/app/views/issueDetails/groupEventDetails/groupEventDetailsContent.tsx
index f7089dffc13f5a..fcc0552bd6aa05 100644
--- a/static/app/views/issueDetails/groupEventDetails/groupEventDetailsContent.tsx
+++ b/static/app/views/issueDetails/groupEventDetails/groupEventDetailsContent.tsx
@@ -8,7 +8,7 @@ import {usePrompt} from 'sentry/actionCreators/prompts';
import Feature from 'sentry/components/acl/feature';
import {GuideAnchor} from 'sentry/components/assistant/guideAnchor';
import {CommitRow} from 'sentry/components/commitRow';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {BreadcrumbsDataSection} from 'sentry/components/events/breadcrumbs/breadcrumbsDataSection';
import {EventContexts} from 'sentry/components/events/contexts';
import {EventDevice} from 'sentry/components/events/device';
diff --git a/static/app/views/issueDetails/groupReplays/groupReplays.tsx b/static/app/views/issueDetails/groupReplays/groupReplays.tsx
index 86a8d69646c23e..8481615d775f9e 100644
--- a/static/app/views/issueDetails/groupReplays/groupReplays.tsx
+++ b/static/app/views/issueDetails/groupReplays/groupReplays.tsx
@@ -34,7 +34,7 @@ import {IconPlay, IconUser} from 'sentry/icons';
import {t, tn} from 'sentry/locale';
import type {Group} from 'sentry/types/group';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {useReplayCountForIssues} from 'sentry/utils/replayCount/useReplayCountForIssues';
import {useLoadReplayReader} from 'sentry/utils/replays/hooks/useLoadReplayReader';
import {useReplayList} from 'sentry/utils/replays/hooks/useReplayList';
diff --git a/static/app/views/issueDetails/groupReplays/useReplaysFromIssue.tsx b/static/app/views/issueDetails/groupReplays/useReplaysFromIssue.tsx
index efb475b6307804..6634543fff53dd 100644
--- a/static/app/views/issueDetails/groupReplays/useReplaysFromIssue.tsx
+++ b/static/app/views/issueDetails/groupReplays/useReplaysFromIssue.tsx
@@ -6,7 +6,7 @@ import {ALL_ACCESS_PROJECTS} from 'sentry/components/pageFilters/constants';
import {DEFAULT_REPLAY_LIST_SORT} from 'sentry/components/replays/table/useReplayTableSort';
import {IssueCategory, type Group} from 'sentry/types/group';
import type {Organization} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {decodeScalar} from 'sentry/utils/queryString';
import type {RequestError} from 'sentry/utils/requestError/requestError';
import {useApi} from 'sentry/utils/useApi';
diff --git a/static/app/views/issueDetails/groupSimilarIssues/similarStackTrace/list.tsx b/static/app/views/issueDetails/groupSimilarIssues/similarStackTrace/list.tsx
index c3f8d0eae68d05..d242e673114908 100644
--- a/static/app/views/issueDetails/groupSimilarIssues/similarStackTrace/list.tsx
+++ b/static/app/views/issueDetails/groupSimilarIssues/similarStackTrace/list.tsx
@@ -14,7 +14,7 @@ import type {Project} from 'sentry/types/project';
import {useOrganization} from 'sentry/utils/useOrganization';
import {SimilarStackTraceItem} from './item';
-import Toolbar from './toolbar';
+import {SimilarToolbar} from './toolbar';
type DefaultProps = {
filteredItems: SimilarItem[];
@@ -84,7 +84,7 @@ export function List({
)}
- {
+export class SimilarToolbar extends Component {
state: State = initialState;
componentWillUnmount() {
@@ -106,7 +106,6 @@ class SimilarToolbar extends Component {
);
}
}
-export default SimilarToolbar;
const StyledToolbarHeader = styled(ToolbarHeader)`
flex: 1;
diff --git a/static/app/views/issueDetails/groupTags/groupTagValues.tsx b/static/app/views/issueDetails/groupTags/groupTagValues.tsx
index e94662b0025d98..cb5a14ca76fd10 100644
--- a/static/app/views/issueDetails/groupTags/groupTagValues.tsx
+++ b/static/app/views/issueDetails/groupTags/groupTagValues.tsx
@@ -23,7 +23,7 @@ import {IconArrow, IconEllipsis, IconMail, IconOpen} from 'sentry/icons';
import {t} from 'sentry/locale';
import type {SavedQueryVersions} from 'sentry/types/organization';
import {percent} from 'sentry/utils';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {SavedQueryDatasets} from 'sentry/utils/discover/types';
import {isUrl} from 'sentry/utils/string/isUrl';
import {useLocation} from 'sentry/utils/useLocation';
diff --git a/static/app/views/issueDetails/metricKitHangProfileSection.tsx b/static/app/views/issueDetails/metricKitHangProfileSection.tsx
index d9fa7f47cab7e3..bbcdea24f99445 100644
--- a/static/app/views/issueDetails/metricKitHangProfileSection.tsx
+++ b/static/app/views/issueDetails/metricKitHangProfileSection.tsx
@@ -1,6 +1,6 @@
import styled from '@emotion/styled';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {
hasFlamegraphData,
StacktraceFlamegraph,
diff --git a/static/app/views/issueDetails/profilePreviewSection.tsx b/static/app/views/issueDetails/profilePreviewSection.tsx
index abd30c0a82fd7f..c627bfdfbc6740 100644
--- a/static/app/views/issueDetails/profilePreviewSection.tsx
+++ b/static/app/views/issueDetails/profilePreviewSection.tsx
@@ -6,7 +6,7 @@ import {LinkButton} from '@sentry/scraps/button';
import {ExternalLink} from '@sentry/scraps/link';
import {SegmentedControl} from '@sentry/scraps/segmentedControl';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {FlamegraphPreview} from 'sentry/components/profiling/flamegraph/flamegraphPreview';
import {QuestionTooltip} from 'sentry/components/questionTooltip';
diff --git a/static/app/views/issueDetails/streamline/eventDetails.tsx b/static/app/views/issueDetails/streamline/eventDetails.tsx
index e3944a248123a1..a50e6f96e6f52b 100644
--- a/static/app/views/issueDetails/streamline/eventDetails.tsx
+++ b/static/app/views/issueDetails/streamline/eventDetails.tsx
@@ -2,7 +2,7 @@ import {useLayoutEffect, useState} from 'react';
import {useTheme} from '@emotion/react';
import styled from '@emotion/styled';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {t} from 'sentry/locale';
import type {Event} from 'sentry/types/event';
import type {Group} from 'sentry/types/group';
diff --git a/static/app/views/issueDetails/streamline/eventDetailsHeader.tsx b/static/app/views/issueDetails/streamline/eventDetailsHeader.tsx
index 231124e8a45bee..4606b6b577e783 100644
--- a/static/app/views/issueDetails/streamline/eventDetailsHeader.tsx
+++ b/static/app/views/issueDetails/streamline/eventDetailsHeader.tsx
@@ -4,7 +4,7 @@ import styled from '@emotion/styled';
import {Flex, Grid} from '@sentry/scraps/layout';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {EnvironmentPageFilter} from 'sentry/components/pageFilters/environment/environmentPageFilter';
import {PageFilterBar} from 'sentry/components/pageFilters/pageFilterBar';
import {
diff --git a/static/app/views/issueDetails/streamline/eventGraph.tsx b/static/app/views/issueDetails/streamline/eventGraph.tsx
index 220b371a215df7..099d7caee24206 100644
--- a/static/app/views/issueDetails/streamline/eventGraph.tsx
+++ b/static/app/views/issueDetails/streamline/eventGraph.tsx
@@ -22,7 +22,7 @@ import type {Group} from 'sentry/types/group';
import type {EventsStats, MultiSeriesEventsStats} from 'sentry/types/organization';
import type {ReleaseMetaBasic} from 'sentry/types/release';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {formatAbbreviatedNumber} from 'sentry/utils/formatters';
import {getConfigForIssueType} from 'sentry/utils/issueTypeConfig';
diff --git a/static/app/views/issueDetails/streamline/foldSection.tsx b/static/app/views/issueDetails/streamline/foldSection.tsx
index 5486d4f285510d..8d18a2c6845a33 100644
--- a/static/app/views/issueDetails/streamline/foldSection.tsx
+++ b/static/app/views/issueDetails/streamline/foldSection.tsx
@@ -13,7 +13,7 @@ import {Disclosure} from '@sentry/scraps/disclosure';
import {Separator, type SeparatorProps} from '@sentry/scraps/separator';
import {Text} from '@sentry/scraps/text';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {t} from 'sentry/locale';
import {trackAnalytics} from 'sentry/utils/analytics';
import {useOrganization} from 'sentry/utils/useOrganization';
diff --git a/static/app/views/issueDetails/streamline/header/header.tsx b/static/app/views/issueDetails/streamline/header/header.tsx
index 5621dc0c9fea3c..556118c7da8f59 100644
--- a/static/app/views/issueDetails/streamline/header/header.tsx
+++ b/static/app/views/issueDetails/streamline/header/header.tsx
@@ -11,7 +11,7 @@ import {Tooltip} from '@sentry/scraps/tooltip';
import {Breadcrumbs} from 'sentry/components/breadcrumbs';
import {Count} from 'sentry/components/count';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {EventMessage} from 'sentry/components/events/eventMessage';
import {FeedbackButton} from 'sentry/components/feedbackButton/feedbackButton';
import {useFeedbackSDKIntegration} from 'sentry/components/feedbackButton/useFeedbackSDKIntegration';
diff --git a/static/app/views/issueDetails/streamline/hooks/useIssueDetailsDiscoverQuery.tsx b/static/app/views/issueDetails/streamline/hooks/useIssueDetailsDiscoverQuery.tsx
index bd615d6b243236..756444811cef3d 100644
--- a/static/app/views/issueDetails/streamline/hooks/useIssueDetailsDiscoverQuery.tsx
+++ b/static/app/views/issueDetails/streamline/hooks/useIssueDetailsDiscoverQuery.tsx
@@ -2,7 +2,7 @@ import {getInterval} from 'sentry/components/charts/utils';
import type {PageFilters} from 'sentry/types/core';
import type {Group} from 'sentry/types/group';
import type {NewQuery, SavedQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {
useGenericDiscoverQuery,
type DiscoverQueryProps,
diff --git a/static/app/views/issueDetails/streamline/sidebar/metricDetectorTriggeredSection.tsx b/static/app/views/issueDetails/streamline/sidebar/metricDetectorTriggeredSection.tsx
index af6976bcc59067..abda381130301e 100644
--- a/static/app/views/issueDetails/streamline/sidebar/metricDetectorTriggeredSection.tsx
+++ b/static/app/views/issueDetails/streamline/sidebar/metricDetectorTriggeredSection.tsx
@@ -8,7 +8,7 @@ import {Flex} from '@sentry/scraps/layout';
import {Text} from '@sentry/scraps/text';
import Feature from 'sentry/components/acl/feature';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {KeyValueList} from 'sentry/components/events/interfaces/keyValueList';
import {AnnotatedText} from 'sentry/components/events/meta/annotatedText';
import {FeedbackButton} from 'sentry/components/feedbackButton/feedbackButton';
diff --git a/static/app/views/issueDetails/streamline/sidebar/sidebar.tsx b/static/app/views/issueDetails/streamline/sidebar/sidebar.tsx
index 246c2b1e1c0452..9da52c748257fb 100644
--- a/static/app/views/issueDetails/streamline/sidebar/sidebar.tsx
+++ b/static/app/views/issueDetails/streamline/sidebar/sidebar.tsx
@@ -4,7 +4,7 @@ import styled from '@emotion/styled';
import {ExternalLink} from '@sentry/scraps/link';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import * as Layout from 'sentry/components/layouts/thirds';
import * as SidebarSection from 'sentry/components/sidebarSection';
import {t, tct} from 'sentry/locale';
diff --git a/static/app/views/issueDetails/traceTimeline/traceTimeline.tsx b/static/app/views/issueDetails/traceTimeline/traceTimeline.tsx
index 2479f9f4be99ab..2cc8606a2f6493 100644
--- a/static/app/views/issueDetails/traceTimeline/traceTimeline.tsx
+++ b/static/app/views/issueDetails/traceTimeline/traceTimeline.tsx
@@ -1,7 +1,7 @@
import {Fragment, useRef} from 'react';
import styled from '@emotion/styled';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {QuestionTooltip} from 'sentry/components/questionTooltip';
import {t} from 'sentry/locale';
import type {Event} from 'sentry/types/event';
diff --git a/static/app/views/issueList/groupListBody.tsx b/static/app/views/issueList/groupListBody.tsx
index fb6d08ac41d755..b7fe8cd7f099ad 100644
--- a/static/app/views/issueList/groupListBody.tsx
+++ b/static/app/views/issueList/groupListBody.tsx
@@ -13,7 +13,7 @@ import {useOrganization} from 'sentry/utils/useOrganization';
import {useSyncedLocalStorageState} from 'sentry/utils/useSyncedLocalStorageState';
import type {IssueUpdateData} from 'sentry/views/issueList/types';
-import NoGroupsHandler from './noGroupsHandler';
+import {NoGroupsHandler} from './noGroupsHandler';
import {SAVED_SEARCHES_SIDEBAR_OPEN_LOCALSTORAGE_KEY} from './utils';
type GroupListBodyProps = {
diff --git a/static/app/views/issueList/noGroupsHandler/index.spec.tsx b/static/app/views/issueList/noGroupsHandler/index.spec.tsx
index a5edb50de5839a..923f33cb467470 100644
--- a/static/app/views/issueList/noGroupsHandler/index.spec.tsx
+++ b/static/app/views/issueList/noGroupsHandler/index.spec.tsx
@@ -2,7 +2,7 @@ import {OrganizationFixture} from 'sentry-fixture/organization';
import {render, screen} from 'sentry-test/reactTestingLibrary';
-import NoGroupsHandler from 'sentry/views/issueList/noGroupsHandler';
+import {NoGroupsHandler} from 'sentry/views/issueList/noGroupsHandler';
describe('NoGroupsHandler', () => {
const defaultProps = {
diff --git a/static/app/views/issueList/noGroupsHandler/index.tsx b/static/app/views/issueList/noGroupsHandler/index.tsx
index 4ce48f22b30cde..0f002c6c0e4001 100644
--- a/static/app/views/issueList/noGroupsHandler/index.tsx
+++ b/static/app/views/issueList/noGroupsHandler/index.tsx
@@ -36,7 +36,7 @@ type State = {
* having no issues be returned from a query. This component will conditionally
* render one of those states.
*/
-class NoGroupsHandler extends Component {
+export class NoGroupsHandler extends Component {
state: State = {
fetchingSentFirstEvent: true,
sentFirstEvent: false,
@@ -220,5 +220,3 @@ class NoGroupsHandler extends Component {
return this.renderEmpty();
}
}
-
-export default NoGroupsHandler;
diff --git a/static/app/views/issueList/overview.tsx b/static/app/views/issueList/overview.tsx
index cd5d0326f81b69..bbcb40783135f3 100644
--- a/static/app/views/issueList/overview.tsx
+++ b/static/app/views/issueList/overview.tsx
@@ -26,7 +26,7 @@ import type {BaseGroup, Group, PriorityLevel} from 'sentry/types/group';
import {GroupStatus} from 'sentry/types/group';
import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
-import CursorPoller from 'sentry/utils/cursorPoller';
+import {CursorPoller} from 'sentry/utils/cursorPoller';
import {getUtcDateString} from 'sentry/utils/dates';
import {getCurrentSentryReactRootSpan} from 'sentry/utils/getCurrentSentryReactRootSpan';
import {parseApiError} from 'sentry/utils/parseApiError';
diff --git a/static/app/views/navigation/navigation.tsx b/static/app/views/navigation/navigation.tsx
index 558b5214375025..97bb378af3b474 100644
--- a/static/app/views/navigation/navigation.tsx
+++ b/static/app/views/navigation/navigation.tsx
@@ -7,7 +7,7 @@ import {Flex} from '@sentry/scraps/layout';
import {SizeProvider} from '@sentry/scraps/sizeContext';
import Feature from 'sentry/components/acl/feature';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import Hook from 'sentry/components/hook';
import {
IconCompass,
diff --git a/static/app/views/navigation/secondary/sections/dashboards/dashboardsSecondaryNavigation.tsx b/static/app/views/navigation/secondary/sections/dashboards/dashboardsSecondaryNavigation.tsx
index 30cb495c54aea4..ee9c3484821c60 100644
--- a/static/app/views/navigation/secondary/sections/dashboards/dashboardsSecondaryNavigation.tsx
+++ b/static/app/views/navigation/secondary/sections/dashboards/dashboardsSecondaryNavigation.tsx
@@ -1,7 +1,7 @@
import {Fragment} from 'react';
import * as Sentry from '@sentry/react';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {t} from 'sentry/locale';
import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
diff --git a/static/app/views/onboarding/components/fallingError.tsx b/static/app/views/onboarding/components/fallingError.tsx
index d74d6e3bda1a97..74b816d92f86ba 100644
--- a/static/app/views/onboarding/components/fallingError.tsx
+++ b/static/app/views/onboarding/components/fallingError.tsx
@@ -20,7 +20,7 @@ type State = {
isFalling: boolean;
};
-class FallingError extends Component {
+export class FallingError extends Component {
state: State = {
isFalling: false,
fallCount: 0,
@@ -140,5 +140,3 @@ class FallingError extends Component {
});
}
}
-
-export default FallingError;
diff --git a/static/app/views/onboarding/welcome.tsx b/static/app/views/onboarding/welcome.tsx
index becd5c5a687d71..783898f783f779 100644
--- a/static/app/views/onboarding/welcome.tsx
+++ b/static/app/views/onboarding/welcome.tsx
@@ -11,7 +11,7 @@ import {Text} from '@sentry/scraps/text';
import {t} from 'sentry/locale';
import {testableTransition} from 'sentry/utils/testableTransition';
-import FallingError from 'sentry/views/onboarding/components/fallingError';
+import {FallingError} from 'sentry/views/onboarding/components/fallingError';
import {WelcomeBackground} from 'sentry/views/onboarding/components/welcomeBackground';
import {WelcomeSkipButton} from 'sentry/views/onboarding/components/welcomeSkipButton';
import {useWelcomeAnalyticsEffect} from 'sentry/views/onboarding/useWelcomeAnalyticsEffect';
diff --git a/static/app/views/organizationLayout/body.tsx b/static/app/views/organizationLayout/body.tsx
index dea5adde028636..089ba45f69ddf3 100644
--- a/static/app/views/organizationLayout/body.tsx
+++ b/static/app/views/organizationLayout/body.tsx
@@ -6,7 +6,7 @@ import {Button} from '@sentry/scraps/button';
import {Flex, Stack} from '@sentry/scraps/layout';
import {Heading, Text} from '@sentry/scraps/text';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {LogoSentry} from 'sentry/components/logoSentry';
import {t, tct} from 'sentry/locale';
import {AlertStore} from 'sentry/stores/alertStore';
diff --git a/static/app/views/organizationStats/index.tsx b/static/app/views/organizationStats/index.tsx
index 120e184d3ade85..1e3a05ae68adf9 100644
--- a/static/app/views/organizationStats/index.tsx
+++ b/static/app/views/organizationStats/index.tsx
@@ -10,7 +10,7 @@ import {Flex} from '@sentry/scraps/layout';
import {OverlayTrigger} from '@sentry/scraps/overlayTrigger';
import type {DateTimeObject} from 'sentry/components/charts/utils';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {HookOrDefault} from 'sentry/components/hookOrDefault';
import * as Layout from 'sentry/components/layouts/thirds';
import {NoProjectMessage} from 'sentry/components/noProjectMessage';
diff --git a/static/app/views/organizationStats/teamInsights/teamMisery.tsx b/static/app/views/organizationStats/teamInsights/teamMisery.tsx
index 64f50d7b87a4d3..2850f670bbc2a0 100644
--- a/static/app/views/organizationStats/teamInsights/teamMisery.tsx
+++ b/static/app/views/organizationStats/teamInsights/teamMisery.tsx
@@ -17,7 +17,7 @@ import type {Organization, SavedQueryVersions} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import type {TableData, TableDataRow} from 'sentry/utils/discover/discoverQuery';
import {DiscoverQuery} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import type {QueryError} from 'sentry/utils/discover/genericDiscoverQuery';
import {transactionSummaryRouteWithQuery} from 'sentry/views/performance/transactionSummary/utils';
diff --git a/static/app/views/performance/breadcrumb.tsx b/static/app/views/performance/breadcrumb.tsx
index 9505ba24703740..145310367b75e0 100644
--- a/static/app/views/performance/breadcrumb.tsx
+++ b/static/app/views/performance/breadcrumb.tsx
@@ -8,7 +8,7 @@ import type {SpanSlug} from 'sentry/utils/performance/suspectSpans/types';
import {DOMAIN_VIEW_BASE_TITLE} from 'sentry/views/insights/pages/settings';
import type {DomainView} from 'sentry/views/insights/pages/useFilters';
-import type Tab from './transactionSummary/tabs';
+import type {Tab} from './transactionSummary/tabs';
import {transactionSummaryRouteWithQuery} from './transactionSummary/utils';
type Props = {
diff --git a/static/app/views/performance/data.tsx b/static/app/views/performance/data.tsx
index 35cc980ec6de64..9538c47b5d113d 100644
--- a/static/app/views/performance/data.tsx
+++ b/static/app/views/performance/data.tsx
@@ -8,7 +8,7 @@ import {COL_WIDTH_UNDEFINED} from 'sentry/components/tables/gridEditable';
import {t, tct} from 'sentry/locale';
import type {NewQuery, Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {decodeScalar} from 'sentry/utils/queryString';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
diff --git a/static/app/views/performance/eap/overviewSpansTable.tsx b/static/app/views/performance/eap/overviewSpansTable.tsx
index 28169a9551cd82..ecbac10a48cb93 100644
--- a/static/app/views/performance/eap/overviewSpansTable.tsx
+++ b/static/app/views/performance/eap/overviewSpansTable.tsx
@@ -10,8 +10,7 @@ import {GridEditable} from 'sentry/components/tables/gridEditable';
import {IconPlay, IconProfiling} from 'sentry/icons';
import {t, tct} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
-import type EventView from 'sentry/utils/discover/eventView';
-import type {EventsMetaType} from 'sentry/utils/discover/eventView';
+import type {EventsMetaType, EventView} from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import type {Theme} from 'sentry/utils/theme';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
diff --git a/static/app/views/performance/eap/segmentSpansTable.spec.tsx b/static/app/views/performance/eap/segmentSpansTable.spec.tsx
index ead4086ab88d38..6df55a4d7c6c01 100644
--- a/static/app/views/performance/eap/segmentSpansTable.spec.tsx
+++ b/static/app/views/performance/eap/segmentSpansTable.spec.tsx
@@ -6,7 +6,7 @@ import {render, screen} from 'sentry-test/reactTestingLibrary';
import {PageFiltersStore} from 'sentry/components/pageFilters/store';
import {ProjectsStore} from 'sentry/stores/projectsStore';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {SegmentSpansTable} from 'sentry/views/performance/eap/segmentSpansTable';
describe('SegmentSpansTable', () => {
diff --git a/static/app/views/performance/eap/segmentSpansTable.tsx b/static/app/views/performance/eap/segmentSpansTable.tsx
index 96c6889cdc7a35..2afc650f11e11e 100644
--- a/static/app/views/performance/eap/segmentSpansTable.tsx
+++ b/static/app/views/performance/eap/segmentSpansTable.tsx
@@ -13,8 +13,7 @@ import {GridEditable} from 'sentry/components/tables/gridEditable';
import {IconPlay, IconProfiling} from 'sentry/icons';
import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
-import type EventView from 'sentry/utils/discover/eventView';
-import type {EventsMetaType} from 'sentry/utils/discover/eventView';
+import type {EventsMetaType, EventView} from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import {decodeScalar} from 'sentry/utils/queryString';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
diff --git a/static/app/views/performance/landing/chart/histogramChart.tsx b/static/app/views/performance/landing/chart/histogramChart.tsx
index f77bc9d00760e7..99a99901b22635 100644
--- a/static/app/views/performance/landing/chart/histogramChart.tsx
+++ b/static/app/views/performance/landing/chart/histogramChart.tsx
@@ -11,7 +11,7 @@ import {Placeholder} from 'sentry/components/placeholder';
import {t} from 'sentry/locale';
import type {Series} from 'sentry/types/echarts';
import type {Organization} from 'sentry/types/organization';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {formatAbbreviatedNumber} from 'sentry/utils/formatters';
import {getDynamicText} from 'sentry/utils/getDynamicText';
import type {HistogramData} from 'sentry/utils/performance/histogram/types';
diff --git a/static/app/views/performance/landing/metricsDataSwitcher.tsx b/static/app/views/performance/landing/metricsDataSwitcher.tsx
index b28b4a5839dcb6..39246425893897 100644
--- a/static/app/views/performance/landing/metricsDataSwitcher.tsx
+++ b/static/app/views/performance/landing/metricsDataSwitcher.tsx
@@ -5,7 +5,7 @@ import {Flex} from '@sentry/scraps/layout';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import type {Organization} from 'sentry/types/organization';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {MetricDataSwitcherOutcome} from 'sentry/utils/performance/contexts/metricsCardinality';
import {useMetricsCardinalityContext} from 'sentry/utils/performance/contexts/metricsCardinality';
import {
diff --git a/static/app/views/performance/landing/metricsDataSwitcherAlert.tsx b/static/app/views/performance/landing/metricsDataSwitcherAlert.tsx
index 32ab2306229356..ee9d53d512e9e2 100644
--- a/static/app/views/performance/landing/metricsDataSwitcherAlert.tsx
+++ b/static/app/views/performance/landing/metricsDataSwitcherAlert.tsx
@@ -11,7 +11,7 @@ import {
} from 'sentry/stores/onboardingDrawerStore';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {MetricDataSwitcherOutcome} from 'sentry/utils/performance/contexts/metricsCardinality';
import {useLocation} from 'sentry/utils/useLocation';
import {useRouter} from 'sentry/utils/useRouter';
diff --git a/static/app/views/performance/landing/utils.spec.tsx b/static/app/views/performance/landing/utils.spec.tsx
index f8e4bc84ea7d9f..13ea68a7193190 100644
--- a/static/app/views/performance/landing/utils.spec.tsx
+++ b/static/app/views/performance/landing/utils.spec.tsx
@@ -5,7 +5,7 @@ import {initializeOrg} from 'sentry-test/initializeOrg';
import {ProjectsStore} from 'sentry/stores/projectsStore';
import type {Project} from 'sentry/types/project';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {getCurrentLandingDisplay} from 'sentry/views/performance/landing/utils';
function initializeData(projects: Project[], query: any = {}) {
diff --git a/static/app/views/performance/landing/utils.tsx b/static/app/views/performance/landing/utils.tsx
index 1c4b7a49f06edb..fc5a9c64ae71e8 100644
--- a/static/app/views/performance/landing/utils.tsx
+++ b/static/app/views/performance/landing/utils.tsx
@@ -3,7 +3,7 @@ import type {Location} from 'history';
import {t} from 'sentry/locale';
import type {Project} from 'sentry/types/project';
import {browserHistory} from 'sentry/utils/browserHistory';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {decodeScalar} from 'sentry/utils/queryString';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {
diff --git a/static/app/views/performance/landing/widgets/components/widgetChartRow.tsx b/static/app/views/performance/landing/widgets/components/widgetChartRow.tsx
index 0df26d6b1ad4bf..a555fc2759fedf 100644
--- a/static/app/views/performance/landing/widgets/components/widgetChartRow.tsx
+++ b/static/app/views/performance/landing/widgets/components/widgetChartRow.tsx
@@ -4,7 +4,7 @@ import styled from '@emotion/styled';
import type {Location} from 'history';
import {PerformanceLayoutBodyRow} from 'sentry/components/performance/layouts';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {usePerformanceDisplayType} from 'sentry/utils/performance/contexts/performanceDisplayContext';
import {getChartSetting} from 'sentry/views/performance/landing/widgets/utils';
import type {PerformanceWidgetSetting} from 'sentry/views/performance/landing/widgets/widgetDefinitions';
diff --git a/static/app/views/performance/landing/widgets/components/widgetContainer.tsx b/static/app/views/performance/landing/widgets/components/widgetContainer.tsx
index 79482cf245eefa..3accb7e1196017 100644
--- a/static/app/views/performance/landing/widgets/components/widgetContainer.tsx
+++ b/static/app/views/performance/landing/widgets/components/widgetContainer.tsx
@@ -13,7 +13,7 @@ import {IconEllipsis} from 'sentry/icons/iconEllipsis';
import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {encodeSort} from 'sentry/utils/discover/eventView';
import type {Field} from 'sentry/utils/discover/fields';
import {DisplayModes, SavedQueryDatasets} from 'sentry/utils/discover/types';
diff --git a/static/app/views/performance/landing/widgets/types.tsx b/static/app/views/performance/landing/widgets/types.tsx
index 23cd15f229d66a..996dd09ef20fa6 100644
--- a/static/app/views/performance/landing/widgets/types.tsx
+++ b/static/app/views/performance/landing/widgets/types.tsx
@@ -4,7 +4,7 @@ import type {Client} from 'sentry/api';
import type {BaseChart} from 'sentry/components/charts/baseChart';
import type {DateString} from 'sentry/types/core';
import type {Organization, OrganizationSummary} from 'sentry/types/organization';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {PerformanceWidgetContainerTypes} from './components/performanceWidgetContainer';
import type {ChartDefinition, PerformanceWidgetSetting} from './widgetDefinitions';
diff --git a/static/app/views/performance/landing/widgets/widgets/lineChartListWidget.tsx b/static/app/views/performance/landing/widgets/widgets/lineChartListWidget.tsx
index a7464a040c41d1..95fb7eca24f1f5 100644
--- a/static/app/views/performance/landing/widgets/widgets/lineChartListWidget.tsx
+++ b/static/app/views/performance/landing/widgets/widgets/lineChartListWidget.tsx
@@ -7,14 +7,14 @@ import {LinkButton} from '@sentry/scraps/button';
import {Link} from '@sentry/scraps/link';
import {Tooltip} from '@sentry/scraps/tooltip';
-import _EventsRequest from 'sentry/components/charts/eventsRequest';
+import {EventsRequest as _EventsRequest} from 'sentry/components/charts/eventsRequest';
import {getInterval} from 'sentry/components/charts/utils';
import {Count} from 'sentry/components/count';
import {TextOverflow} from 'sentry/components/textOverflow';
import {Truncate} from 'sentry/components/truncate';
import {t, tct} from 'sentry/locale';
import {DiscoverQuery} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {formatPercentage} from 'sentry/utils/number/formatPercentage';
import {
diff --git a/static/app/views/performance/landing/widgets/widgets/mobileReleaseComparisonListWidget.tsx b/static/app/views/performance/landing/widgets/widgets/mobileReleaseComparisonListWidget.tsx
index cd69c0021d49cc..1af97bb755047d 100644
--- a/static/app/views/performance/landing/widgets/widgets/mobileReleaseComparisonListWidget.tsx
+++ b/static/app/views/performance/landing/widgets/widgets/mobileReleaseComparisonListWidget.tsx
@@ -6,7 +6,7 @@ import pick from 'lodash/pick';
import {LinkButton} from '@sentry/scraps/button';
import type {RenderProps} from 'sentry/components/charts/eventsRequest';
-import EventsRequest from 'sentry/components/charts/eventsRequest';
+import {EventsRequest} from 'sentry/components/charts/eventsRequest';
import {getInterval} from 'sentry/components/charts/utils';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
diff --git a/static/app/views/performance/landing/widgets/widgets/performanceScoreListWidget.tsx b/static/app/views/performance/landing/widgets/widgets/performanceScoreListWidget.tsx
index 306f01bf2aca95..483ed9d3107f29 100644
--- a/static/app/views/performance/landing/widgets/widgets/performanceScoreListWidget.tsx
+++ b/static/app/views/performance/landing/widgets/widgets/performanceScoreListWidget.tsx
@@ -7,7 +7,7 @@ import {LinkButton} from '@sentry/scraps/button';
import {ExternalLink} from '@sentry/scraps/link';
import {Tooltip} from '@sentry/scraps/tooltip';
-import _EventsRequest from 'sentry/components/charts/eventsRequest';
+import {EventsRequest as _EventsRequest} from 'sentry/components/charts/eventsRequest';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {Truncate} from 'sentry/components/truncate';
import {t} from 'sentry/locale';
diff --git a/static/app/views/performance/landing/widgets/widgets/singleFieldAreaWidget.tsx b/static/app/views/performance/landing/widgets/widgets/singleFieldAreaWidget.tsx
index 393d4f9defc0e0..351759edf353f6 100644
--- a/static/app/views/performance/landing/widgets/widgets/singleFieldAreaWidget.tsx
+++ b/static/app/views/performance/landing/widgets/widgets/singleFieldAreaWidget.tsx
@@ -2,7 +2,7 @@ import {Fragment, useMemo} from 'react';
import styled from '@emotion/styled';
import pick from 'lodash/pick';
-import _EventsRequest from 'sentry/components/charts/eventsRequest';
+import {EventsRequest as _EventsRequest} from 'sentry/components/charts/eventsRequest';
import {getInterval, getPreviousSeriesName} from 'sentry/components/charts/utils';
import {t} from 'sentry/locale';
import {axisLabelFormatter} from 'sentry/utils/discover/charts';
diff --git a/static/app/views/performance/landing/widgets/widgets/stackedAreaChartListWidget.tsx b/static/app/views/performance/landing/widgets/widgets/stackedAreaChartListWidget.tsx
index cc58270f38d7bc..42aaee3ec2dae3 100644
--- a/static/app/views/performance/landing/widgets/widgets/stackedAreaChartListWidget.tsx
+++ b/static/app/views/performance/landing/widgets/widgets/stackedAreaChartListWidget.tsx
@@ -2,7 +2,7 @@ import {Fragment, useMemo, useState} from 'react';
import {useTheme} from '@emotion/react';
import pick from 'lodash/pick';
-import _EventsRequest from 'sentry/components/charts/eventsRequest';
+import {EventsRequest as _EventsRequest} from 'sentry/components/charts/eventsRequest';
import {StackedAreaChart} from 'sentry/components/charts/stackedAreaChart';
import {getInterval} from 'sentry/components/charts/utils';
import {Count} from 'sentry/components/count';
diff --git a/static/app/views/performance/newTraceDetails/traceApi/useReplayTraceMeta.tsx b/static/app/views/performance/newTraceDetails/traceApi/useReplayTraceMeta.tsx
index 9f70e9f6815849..81fe5a5f3eb9a5 100644
--- a/static/app/views/performance/newTraceDetails/traceApi/useReplayTraceMeta.tsx
+++ b/static/app/views/performance/newTraceDetails/traceApi/useReplayTraceMeta.tsx
@@ -4,7 +4,7 @@ import type {Location} from 'history';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
import {getTimeStampFromTableDateField, getUtcDateString} from 'sentry/utils/dates';
import type {TableDataRow} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {useApiQuery} from 'sentry/utils/queryClient';
import {useOrganization} from 'sentry/utils/useOrganization';
import type {ReplayTrace} from 'sentry/views/replays/detail/trace/useReplayTraces';
diff --git a/static/app/views/performance/newTraceDetails/traceApi/useTraceAverageTransactionDuration.tsx b/static/app/views/performance/newTraceDetails/traceApi/useTraceAverageTransactionDuration.tsx
index d63beaba7c4096..c893e81ed003c7 100644
--- a/static/app/views/performance/newTraceDetails/traceApi/useTraceAverageTransactionDuration.tsx
+++ b/static/app/views/performance/newTraceDetails/traceApi/useTraceAverageTransactionDuration.tsx
@@ -2,7 +2,7 @@ import type {Location} from 'history';
import type {Organization} from 'sentry/types/organization';
import {useDiscoverQuery} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import type {TransactionNode} from 'sentry/views/performance/newTraceDetails/traceModels/traceTreeNode/transactionNode';
diff --git a/static/app/views/performance/newTraceDetails/traceDrawer/details/issues/issueSummary.tsx b/static/app/views/performance/newTraceDetails/traceDrawer/details/issues/issueSummary.tsx
index 2de4c973f09c86..a9a7e84e51a26a 100644
--- a/static/app/views/performance/newTraceDetails/traceDrawer/details/issues/issueSummary.tsx
+++ b/static/app/views/performance/newTraceDetails/traceDrawer/details/issues/issueSummary.tsx
@@ -3,7 +3,7 @@ import styled from '@emotion/styled';
import {Link} from '@sentry/scraps/link';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {EventTitleError} from 'sentry/components/eventTitleError';
import {GroupTitle} from 'sentry/components/groupTitle';
import {extractSelectionParameters} from 'sentry/components/pageFilters/parse';
diff --git a/static/app/views/performance/newTraceDetails/traceDrawer/details/span/index.tsx b/static/app/views/performance/newTraceDetails/traceDrawer/details/span/index.tsx
index 6a22e2afec8314..23583128173c41 100644
--- a/static/app/views/performance/newTraceDetails/traceDrawer/details/span/index.tsx
+++ b/static/app/views/performance/newTraceDetails/traceDrawer/details/span/index.tsx
@@ -14,7 +14,7 @@ import type {NewQuery, Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
import {LogsAnalyticsPageSource} from 'sentry/utils/analytics/logsAnalyticsEvent';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useLocation} from 'sentry/utils/useLocation';
import {useProjects} from 'sentry/utils/useProjects';
diff --git a/static/app/views/performance/newTraceDetails/traceDrawer/details/transaction/sections/entries.tsx b/static/app/views/performance/newTraceDetails/traceDrawer/details/transaction/sections/entries.tsx
index 71b05d3808785a..93d0b5c5c62e5a 100644
--- a/static/app/views/performance/newTraceDetails/traceDrawer/details/transaction/sections/entries.tsx
+++ b/static/app/views/performance/newTraceDetails/traceDrawer/details/transaction/sections/entries.tsx
@@ -1,6 +1,6 @@
import {Fragment} from 'react';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {Csp} from 'sentry/components/events/interfaces/csp';
import {Exception} from 'sentry/components/events/interfaces/exception';
import {Generic} from 'sentry/components/events/interfaces/generic';
diff --git a/static/app/views/performance/newTraceDetails/traceDrawer/details/transaction/sections/request.tsx b/static/app/views/performance/newTraceDetails/traceDrawer/details/transaction/sections/request.tsx
index 0f9a666d0e83dc..74c0701af7ed74 100644
--- a/static/app/views/performance/newTraceDetails/traceDrawer/details/transaction/sections/request.tsx
+++ b/static/app/views/performance/newTraceDetails/traceDrawer/details/transaction/sections/request.tsx
@@ -5,7 +5,7 @@ import {CodeBlock} from '@sentry/scraps/code';
import {ExternalLink} from '@sentry/scraps/link';
import {SegmentedControl} from '@sentry/scraps/segmentedControl';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {EventDataSection} from 'sentry/components/events/eventDataSection';
import {getTransformedData} from 'sentry/components/events/interfaces/request/getTransformedData';
import {GraphQlRequestBody} from 'sentry/components/events/interfaces/request/graphQlRequestBody';
diff --git a/static/app/views/performance/newTraceDetails/traceDrawer/traceDrawer.tsx b/static/app/views/performance/newTraceDetails/traceDrawer/traceDrawer.tsx
index 2aa5e8d8524dbe..d3b8bec5015c82 100644
--- a/static/app/views/performance/newTraceDetails/traceDrawer/traceDrawer.tsx
+++ b/static/app/views/performance/newTraceDetails/traceDrawer/traceDrawer.tsx
@@ -6,7 +6,7 @@ import {Button} from '@sentry/scraps/button';
import {IconCircleFill, IconClose, IconPin} from 'sentry/icons';
import {t} from 'sentry/locale';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {
cancelAnimationTimeout,
requestAnimationTimeout,
diff --git a/static/app/views/performance/newTraceDetails/traceHeader/breadcrumbs.tsx b/static/app/views/performance/newTraceDetails/traceHeader/breadcrumbs.tsx
index d55e18128d5354..5926de65e5ce4e 100644
--- a/static/app/views/performance/newTraceDetails/traceHeader/breadcrumbs.tsx
+++ b/static/app/views/performance/newTraceDetails/traceHeader/breadcrumbs.tsx
@@ -23,7 +23,7 @@ import {
import {DOMAIN_VIEW_TITLES} from 'sentry/views/insights/pages/types';
import type {DomainView} from 'sentry/views/insights/pages/useFilters';
import {ModuleName} from 'sentry/views/insights/types';
-import Tab from 'sentry/views/performance/transactionSummary/tabs';
+import {Tab} from 'sentry/views/performance/transactionSummary/tabs';
import {getTransactionSummaryBaseUrl} from 'sentry/views/performance/transactionSummary/utils';
import {getPerformanceBaseUrl} from 'sentry/views/performance/utils';
import {makeTracesPathname} from 'sentry/views/traces/pathnames';
diff --git a/static/app/views/performance/newTraceDetails/traceHeader/index.spec.tsx b/static/app/views/performance/newTraceDetails/traceHeader/index.spec.tsx
index 5fdc28982fd4b7..de60f6a53b2eb3 100644
--- a/static/app/views/performance/newTraceDetails/traceHeader/index.spec.tsx
+++ b/static/app/views/performance/newTraceDetails/traceHeader/index.spec.tsx
@@ -5,7 +5,7 @@ import {OrganizationFixture} from 'sentry-fixture/organization';
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import type {Organization} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {useLocation} from 'sentry/utils/useLocation';
import {
TraceMetaDataHeader,
diff --git a/static/app/views/performance/newTraceDetails/traceHeader/index.tsx b/static/app/views/performance/newTraceDetails/traceHeader/index.tsx
index 1f9ec543b8d03f..5839228c410902 100644
--- a/static/app/views/performance/newTraceDetails/traceHeader/index.tsx
+++ b/static/app/views/performance/newTraceDetails/traceHeader/index.tsx
@@ -5,7 +5,7 @@ import {FeedbackButton} from 'sentry/components/feedbackButton/feedbackButton';
import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {useLocation} from 'sentry/utils/useLocation';
import {useProjects} from 'sentry/utils/useProjects';
import {
diff --git a/static/app/views/performance/newTraceDetails/traceOpenInExploreButton.tsx b/static/app/views/performance/newTraceDetails/traceOpenInExploreButton.tsx
index f46034e3d46c8a..129628f4d361e6 100644
--- a/static/app/views/performance/newTraceDetails/traceOpenInExploreButton.tsx
+++ b/static/app/views/performance/newTraceDetails/traceOpenInExploreButton.tsx
@@ -2,7 +2,7 @@ import {LinkButton} from '@sentry/scraps/button';
import {MutableSearch} from 'sentry/components/searchSyntax/mutableSearch';
import {t} from 'sentry/locale';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {useLocation} from 'sentry/utils/useLocation';
import {useOrganization} from 'sentry/utils/useOrganization';
import {Mode} from 'sentry/views/explore/queryParams/mode';
diff --git a/static/app/views/performance/newTraceDetails/traceWaterfall.tsx b/static/app/views/performance/newTraceDetails/traceWaterfall.tsx
index 1654174aac9d32..557e42c20ff831 100644
--- a/static/app/views/performance/newTraceDetails/traceWaterfall.tsx
+++ b/static/app/views/performance/newTraceDetails/traceWaterfall.tsx
@@ -22,7 +22,7 @@ import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {trackAnalytics} from 'sentry/utils/analytics';
import {DemoTourElement, DemoTourStep} from 'sentry/utils/demoMode/demoTours';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {
cancelAnimationTimeout,
requestAnimationTimeout,
diff --git a/static/app/views/performance/newTraceDetails/useTraceEventView.tsx b/static/app/views/performance/newTraceDetails/useTraceEventView.tsx
index c22d9fb4d81b18..b3aa87fba8005a 100644
--- a/static/app/views/performance/newTraceDetails/useTraceEventView.tsx
+++ b/static/app/views/performance/newTraceDetails/useTraceEventView.tsx
@@ -2,7 +2,7 @@ import {useMemo} from 'react';
import {ALL_ACCESS_PROJECTS} from 'sentry/components/pageFilters/constants';
import type {NewQuery} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import type {TraceViewQueryParams} from './useTraceQueryParams';
diff --git a/static/app/views/performance/onboarding.tsx b/static/app/views/performance/onboarding.tsx
index 256c4ffdc5d7f7..e9e7810849e17b 100644
--- a/static/app/views/performance/onboarding.tsx
+++ b/static/app/views/performance/onboarding.tsx
@@ -23,7 +23,8 @@ import {UnsupportedAlert} from 'sentry/components/alerts/unsupportedAlert';
import {GuidedSteps} from 'sentry/components/guidedSteps/guidedSteps';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import type {TourStep} from 'sentry/components/modals/featureTourModal';
-import FeatureTourModal, {
+import {
+ FeatureTourModal,
TourImage,
TourText,
} from 'sentry/components/modals/featureTourModal';
diff --git a/static/app/views/performance/table.spec.tsx b/static/app/views/performance/table.spec.tsx
index ef6ac3b8bb7ede..ee9f72832bebbd 100644
--- a/static/app/views/performance/table.spec.tsx
+++ b/static/app/views/performance/table.spec.tsx
@@ -5,7 +5,7 @@ import {initializeData as _initializeData} from 'sentry-test/performance/initial
import {render, screen, userEvent, within} from 'sentry-test/reactTestingLibrary';
import {ProjectsStore} from 'sentry/stores/projectsStore';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MEPSettingProvider} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {OrganizationContext} from 'sentry/views/organizationContext';
diff --git a/static/app/views/performance/table.tsx b/static/app/views/performance/table.tsx
index 352241bb71559f..b1f6cca904900c 100644
--- a/static/app/views/performance/table.tsx
+++ b/static/app/views/performance/table.tsx
@@ -22,8 +22,7 @@ import {trackAnalytics} from 'sentry/utils/analytics';
import {browserHistory} from 'sentry/utils/browserHistory';
import type {TableData, TableDataRow} from 'sentry/utils/discover/discoverQuery';
import {DiscoverQuery} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
-import type {MetaType} from 'sentry/utils/discover/eventView';
+import type {EventView, MetaType} from 'sentry/utils/discover/eventView';
import {isFieldSortable} from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import {fieldAlignment, getAggregateAlias} from 'sentry/utils/discover/fields';
diff --git a/static/app/views/performance/transactionEvents.spec.tsx b/static/app/views/performance/transactionEvents.spec.tsx
index 76c58b9b45a457..68f5451d553da7 100644
--- a/static/app/views/performance/transactionEvents.spec.tsx
+++ b/static/app/views/performance/transactionEvents.spec.tsx
@@ -6,7 +6,7 @@ import {render, screen} from 'sentry-test/reactTestingLibrary';
import {ProjectsStore} from 'sentry/stores/projectsStore';
import {WebVital} from 'sentry/utils/fields';
import TransactionSummaryLayout from 'sentry/views/performance/transactionSummary/layout';
-import TransactionSummaryTab from 'sentry/views/performance/transactionSummary/tabs';
+import {Tab as TransactionSummaryTab} from 'sentry/views/performance/transactionSummary/tabs';
import TransactionEvents from 'sentry/views/performance/transactionSummary/transactionEvents';
// XXX(epurkhiser): This appears to also be tested by ./transactionSummary/transactionEvents/index.spec.tsx
diff --git a/static/app/views/performance/transactionSummary/header.spec.tsx b/static/app/views/performance/transactionSummary/header.spec.tsx
index 0ec49294401935..c52d8ffd21ccda 100644
--- a/static/app/views/performance/transactionSummary/header.spec.tsx
+++ b/static/app/views/performance/transactionSummary/header.spec.tsx
@@ -5,9 +5,9 @@ import {initializeOrg} from 'sentry-test/initializeOrg';
import {render, screen} from 'sentry-test/reactTestingLibrary';
import type {PlatformKey} from 'sentry/types/project';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {TransactionHeader} from 'sentry/views/performance/transactionSummary/header';
-import Tab from 'sentry/views/performance/transactionSummary/tabs';
+import {Tab} from 'sentry/views/performance/transactionSummary/tabs';
type InitialOpts = {
features?: string[];
diff --git a/static/app/views/performance/transactionSummary/header.tsx b/static/app/views/performance/transactionSummary/header.tsx
index c3971f5a9b193d..1584db784ebce7 100644
--- a/static/app/views/performance/transactionSummary/header.tsx
+++ b/static/app/views/performance/transactionSummary/header.tsx
@@ -17,7 +17,7 @@ import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {MetricsCardinalityContext} from 'sentry/utils/performance/contexts/metricsCardinality';
import {isProfilingSupportedOrProjectHasProfiles} from 'sentry/utils/profiling/platforms';
import {useReplayCountForTransactions} from 'sentry/utils/replayCount/useReplayCountForTransactions';
@@ -42,7 +42,7 @@ import {tagsRouteWithQuery} from 'sentry/views/performance/transactionSummary/tr
import {transactionSummaryRouteWithQuery} from 'sentry/views/performance/transactionSummary/utils';
import {getSelectedProjectPlatforms} from 'sentry/views/performance/utils';
-import Tab from './tabs';
+import {Tab} from './tabs';
import TeamKeyTransactionButton from './teamKeyTransactionButton';
import TransactionThresholdButton from './transactionThresholdButton';
import type {TransactionThresholdMetric} from './transactionThresholdModal';
diff --git a/static/app/views/performance/transactionSummary/layout.tsx b/static/app/views/performance/transactionSummary/layout.tsx
index 260ee7fb5df5cb..9a2263edefc4c3 100644
--- a/static/app/views/performance/transactionSummary/layout.tsx
+++ b/static/app/views/performance/transactionSummary/layout.tsx
@@ -3,12 +3,12 @@ import * as Sentry from '@sentry/react';
import type {Location} from 'history';
import {t} from 'sentry/locale';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {useLocation} from 'sentry/utils/useLocation';
import {useOrganization} from 'sentry/utils/useOrganization';
import {useProjects} from 'sentry/utils/useProjects';
import {PageLayout} from 'sentry/views/performance/transactionSummary/pageLayout';
-import Tab from 'sentry/views/performance/transactionSummary/tabs';
+import {Tab} from 'sentry/views/performance/transactionSummary/tabs';
import {generateTransactionEventsEventView} from 'sentry/views/performance/transactionSummary/transactionEvents/utils';
import {generateTransactionOverviewEventView} from 'sentry/views/performance/transactionSummary/transactionOverview/utils';
import {generateTransactionReplaysEventView} from 'sentry/views/performance/transactionSummary/transactionReplays/utils';
diff --git a/static/app/views/performance/transactionSummary/pageLayout.tsx b/static/app/views/performance/transactionSummary/pageLayout.tsx
index 8926e2284b03dd..98b10b4c75a23c 100644
--- a/static/app/views/performance/transactionSummary/pageLayout.tsx
+++ b/static/app/views/performance/transactionSummary/pageLayout.tsx
@@ -24,7 +24,7 @@ import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
import {browserHistory} from 'sentry/utils/browserHistory';
import {DiscoverQuery} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {
MetricsCardinalityProvider,
useMetricsCardinalityContext,
@@ -47,7 +47,7 @@ import {profilesRouteWithQuery} from './transactionProfiles/utils';
import {replaysRouteWithQuery} from './transactionReplays/utils';
import {tagsRouteWithQuery} from './transactionTags/utils';
import {TransactionHeader} from './header';
-import Tab from './tabs';
+import {Tab} from './tabs';
import type {TransactionThresholdMetric} from './transactionThresholdModal';
import {generateTransactionSummaryRoute, transactionSummaryRouteWithQuery} from './utils';
diff --git a/static/app/views/performance/transactionSummary/tabs.tsx b/static/app/views/performance/transactionSummary/tabs.tsx
index eb68a5a1bba570..7038b1677cb0fb 100644
--- a/static/app/views/performance/transactionSummary/tabs.tsx
+++ b/static/app/views/performance/transactionSummary/tabs.tsx
@@ -1,9 +1,7 @@
-enum Tab {
+export enum Tab {
TRANSACTION_SUMMARY = 'summary',
TAGS = 'tags',
EVENTS = 'events',
REPLAYS = 'replays',
PROFILING = 'profiling',
}
-
-export default Tab;
diff --git a/static/app/views/performance/transactionSummary/teamKeyTransactionButton.spec.tsx b/static/app/views/performance/transactionSummary/teamKeyTransactionButton.spec.tsx
index 13a5f4552360a3..89d73afe89917e 100644
--- a/static/app/views/performance/transactionSummary/teamKeyTransactionButton.spec.tsx
+++ b/static/app/views/performance/transactionSummary/teamKeyTransactionButton.spec.tsx
@@ -7,7 +7,7 @@ import {act, render, screen, userEvent, waitFor} from 'sentry-test/reactTestingL
import {ProjectsStore} from 'sentry/stores/projectsStore';
import {TeamStore} from 'sentry/stores/teamStore';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MAX_TEAM_KEY_TRANSACTIONS} from 'sentry/utils/performance/constants';
import TeamKeyTransactionButton from 'sentry/views/performance/transactionSummary/teamKeyTransactionButton';
diff --git a/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx b/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx
index a2f27967ea1169..d0d468eed97ea6 100644
--- a/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx
+++ b/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx
@@ -9,7 +9,7 @@ import {t, tn} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {useTeams} from 'sentry/utils/useTeams';
import {withProjects} from 'sentry/utils/withProjects';
diff --git a/static/app/views/performance/transactionSummary/transactionEvents/content.spec.tsx b/static/app/views/performance/transactionSummary/transactionEvents/content.spec.tsx
index 411bbd18657f07..84b47ccc2384f1 100644
--- a/static/app/views/performance/transactionSummary/transactionEvents/content.spec.tsx
+++ b/static/app/views/performance/transactionSummary/transactionEvents/content.spec.tsx
@@ -6,7 +6,7 @@ import {act, render, screen} from 'sentry-test/reactTestingLibrary';
import {textWithMarkupMatcher} from 'sentry-test/utils';
import {ProjectsStore} from 'sentry/stores/projectsStore';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {
SPAN_OP_BREAKDOWN_FIELDS,
SPAN_OP_RELATIVE_BREAKDOWN_FIELD,
diff --git a/static/app/views/performance/transactionSummary/transactionEvents/content.tsx b/static/app/views/performance/transactionSummary/transactionEvents/content.tsx
index c0aef722cc4b8d..2f3016e48e0ab2 100644
--- a/static/app/views/performance/transactionSummary/transactionEvents/content.tsx
+++ b/static/app/views/performance/transactionSummary/transactionEvents/content.tsx
@@ -19,7 +19,7 @@ import {DataCategory} from 'sentry/types/core';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {SavedQueryDatasets} from 'sentry/utils/discover/types';
import type {WebVital} from 'sentry/utils/fields';
import {decodeScalar} from 'sentry/utils/queryString';
diff --git a/static/app/views/performance/transactionSummary/transactionEvents/eventsTable.spec.tsx b/static/app/views/performance/transactionSummary/transactionEvents/eventsTable.spec.tsx
index 4098a5e210201c..dc4a689cb69894 100644
--- a/static/app/views/performance/transactionSummary/transactionEvents/eventsTable.spec.tsx
+++ b/static/app/views/performance/transactionSummary/transactionEvents/eventsTable.spec.tsx
@@ -5,7 +5,7 @@ import {initializeOrg} from 'sentry-test/initializeOrg';
import {render, screen, waitForElementToBeRemoved} from 'sentry-test/reactTestingLibrary';
import {ProjectsStore} from 'sentry/stores/projectsStore';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {SPAN_OP_RELATIVE_BREAKDOWN_FIELD} from 'sentry/utils/discover/fields';
import {EventsTable} from 'sentry/views/performance/transactionSummary/transactionEvents/eventsTable';
import {
diff --git a/static/app/views/performance/transactionSummary/transactionEvents/eventsTable.tsx b/static/app/views/performance/transactionSummary/transactionEvents/eventsTable.tsx
index 9c20943b2bd8ca..a0d08c2dee3e47 100644
--- a/static/app/views/performance/transactionSummary/transactionEvents/eventsTable.tsx
+++ b/static/app/views/performance/transactionSummary/transactionEvents/eventsTable.tsx
@@ -23,7 +23,7 @@ import {trackAnalytics} from 'sentry/utils/analytics';
import {toArray} from 'sentry/utils/array/toArray';
import type {TableData, TableDataRow} from 'sentry/utils/discover/discoverQuery';
import {DiscoverQuery} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {isFieldSortable} from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import {
diff --git a/static/app/views/performance/transactionSummary/transactionEvents/index.spec.tsx b/static/app/views/performance/transactionSummary/transactionEvents/index.spec.tsx
index 34d162990980e2..8b6fb566261c93 100644
--- a/static/app/views/performance/transactionSummary/transactionEvents/index.spec.tsx
+++ b/static/app/views/performance/transactionSummary/transactionEvents/index.spec.tsx
@@ -5,7 +5,7 @@ import {act, render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import {ProjectsStore} from 'sentry/stores/projectsStore';
import {MEPSettingProvider} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
import TransactionSummaryLayout from 'sentry/views/performance/transactionSummary/layout';
-import TransactionSummaryTab from 'sentry/views/performance/transactionSummary/tabs';
+import {Tab as TransactionSummaryTab} from 'sentry/views/performance/transactionSummary/tabs';
import TransactionEvents from 'sentry/views/performance/transactionSummary/transactionEvents';
import {
EVENTS_TABLE_RESPONSE_FIELDS,
diff --git a/static/app/views/performance/transactionSummary/transactionEvents/operationSort.tsx b/static/app/views/performance/transactionSummary/transactionEvents/operationSort.tsx
index 1ac47e6b92f70f..3ae4b607b6283f 100644
--- a/static/app/views/performance/transactionSummary/transactionEvents/operationSort.tsx
+++ b/static/app/views/performance/transactionSummary/transactionEvents/operationSort.tsx
@@ -12,7 +12,7 @@ import {MenuItem} from 'sentry/components/menuItem';
import {t} from 'sentry/locale';
import {browserHistory} from 'sentry/utils/browserHistory';
import type {TableData} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
export type TitleProps = Partial>;
diff --git a/static/app/views/performance/transactionSummary/transactionEvents/utils.tsx b/static/app/views/performance/transactionSummary/transactionEvents/utils.tsx
index 1732eb0ffdfc3d..b8b4de7541e293 100644
--- a/static/app/views/performance/transactionSummary/transactionEvents/utils.tsx
+++ b/static/app/views/performance/transactionSummary/transactionEvents/utils.tsx
@@ -3,7 +3,7 @@ import type {Location, Query} from 'history';
import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import type {TableDataRow} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {
isAggregateField,
SPAN_OP_BREAKDOWN_FIELDS,
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/charts.tsx b/static/app/views/performance/transactionSummary/transactionOverview/charts.tsx
index 1e5586e8496f21..2cf9e3b580e3d0 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/charts.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/charts.tsx
@@ -13,7 +13,7 @@ import type {SelectValue} from 'sentry/types/core';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {useMetricsCardinalityContext} from 'sentry/utils/performance/contexts/metricsCardinality';
import {useMEPSettingContext} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
import {removeHistogramQueryStrings} from 'sentry/utils/performance/histogram';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/content.spec.tsx b/static/app/views/performance/transactionSummary/transactionOverview/content.spec.tsx
index 8af9c0d836ae2e..eaf472bdf644a6 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/content.spec.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/content.spec.tsx
@@ -5,7 +5,7 @@ import {initializeOrg} from 'sentry-test/initializeOrg';
import {render, screen} from 'sentry-test/reactTestingLibrary';
import type {InjectedRouter} from 'sentry/types/legacyReactRouter';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MEPSettingProvider} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
import {SpanOperationBreakdownFilter} from 'sentry/views/performance/transactionSummary/filter';
import SummaryContent from 'sentry/views/performance/transactionSummary/transactionOverview/content';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/content.tsx b/static/app/views/performance/transactionSummary/transactionOverview/content.tsx
index eb4fa735f49365..b1b3cf99a3a32d 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/content.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/content.tsx
@@ -23,7 +23,7 @@ import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {generateQueryWithTag} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {
formatTagKey,
isRelativeSpanOperationBreakdownField,
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/durationChart/content.tsx b/static/app/views/performance/transactionSummary/transactionOverview/durationChart/content.tsx
index 0f46f2665178fc..f4a11774c7b8dc 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/durationChart/content.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/durationChart/content.tsx
@@ -7,7 +7,7 @@ import ChartZoom from 'sentry/components/charts/chartZoom';
import {ErrorPanel} from 'sentry/components/charts/errorPanel';
import type {LineChartProps} from 'sentry/components/charts/lineChart';
import ReleaseSeries from 'sentry/components/charts/releaseSeries';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
import {Placeholder} from 'sentry/components/placeholder';
import {IconWarning} from 'sentry/icons';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/durationChart/index.tsx b/static/app/views/performance/transactionSummary/transactionOverview/durationChart/index.tsx
index d99ddb81fb751f..b2bb4270f5aeae 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/durationChart/index.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/durationChart/index.tsx
@@ -2,7 +2,7 @@ import {Fragment} from 'react';
import {useTheme} from '@emotion/react';
import type {Query} from 'history';
-import EventsRequest from 'sentry/components/charts/eventsRequest';
+import {EventsRequest} from 'sentry/components/charts/eventsRequest';
import {HeaderTitleLegend} from 'sentry/components/charts/styles';
import {getInterval, getSeriesSelection} from 'sentry/components/charts/utils';
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/durationPercentileChart/content.tsx b/static/app/views/performance/transactionSummary/transactionOverview/durationPercentileChart/content.tsx
index c48e3f0fcaa081..4f850815e84d59 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/durationPercentileChart/content.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/durationPercentileChart/content.tsx
@@ -7,7 +7,7 @@ import {IconWarning} from 'sentry/icons';
import type {OrganizationSummary} from 'sentry/types/organization';
import {defined} from 'sentry/utils';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {useApiQuery} from 'sentry/utils/queryClient';
import {
filterToColor,
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/index.spec.tsx b/static/app/views/performance/transactionSummary/transactionOverview/index.spec.tsx
index 8c6bb8a8da1a9f..76e4acedf64b27 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/index.spec.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/index.spec.tsx
@@ -19,7 +19,7 @@ import type {Project} from 'sentry/types/project';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {MetricsCardinalityProvider} from 'sentry/utils/performance/contexts/metricsCardinality';
import TransactionSummaryLayout from 'sentry/views/performance/transactionSummary/layout';
-import TransactionSummaryTab from 'sentry/views/performance/transactionSummary/tabs';
+import {Tab as TransactionSummaryTab} from 'sentry/views/performance/transactionSummary/tabs';
import TransactionSummary from 'sentry/views/performance/transactionSummary/transactionOverview';
const teams = [
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/index.tsx b/static/app/views/performance/transactionSummary/transactionOverview/index.tsx
index 34bb7ed5b606e5..876956bd55dacc 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/index.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/index.tsx
@@ -8,7 +8,7 @@ import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import type {Organization} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
import {useDiscoverQuery} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import type {Column, QueryFieldValue} from 'sentry/utils/discover/fields';
import type {WebVital} from 'sentry/utils/fields';
import {useMetricsCardinalityContext} from 'sentry/utils/performance/contexts/metricsCardinality';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/latencyChart/content.tsx b/static/app/views/performance/transactionSummary/transactionOverview/latencyChart/content.tsx
index 2ec1639db7db48..0a2f8e6b0eac37 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/latencyChart/content.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/latencyChart/content.tsx
@@ -10,7 +10,7 @@ import {IconWarning} from 'sentry/icons';
import {t} from 'sentry/locale';
import type {OrganizationSummary} from 'sentry/types/organization';
import {toArray} from 'sentry/utils/array/toArray';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {formatPercentage} from 'sentry/utils/number/formatPercentage';
import {Histogram} from 'sentry/utils/performance/histogram';
import {HistogramQuery} from 'sentry/utils/performance/histogram/histogramQuery';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/sidebarCharts.tsx b/static/app/views/performance/transactionSummary/transactionOverview/sidebarCharts.tsx
index a0edb6a12e8a21..bc3dca4274e843 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/sidebarCharts.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/sidebarCharts.tsx
@@ -3,11 +3,11 @@ import styled from '@emotion/styled';
import ChartZoom from 'sentry/components/charts/chartZoom';
import {ErrorPanel} from 'sentry/components/charts/errorPanel';
-import EventsRequest from 'sentry/components/charts/eventsRequest';
+import {EventsRequest} from 'sentry/components/charts/eventsRequest';
import type {LineChartProps} from 'sentry/components/charts/lineChart';
import {LineChart} from 'sentry/components/charts/lineChart';
import {SectionHeading} from 'sentry/components/charts/styles';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
import {getInterval} from 'sentry/components/charts/utils';
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
@@ -18,7 +18,7 @@ import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import {getUtcToLocalDateObject} from 'sentry/utils/dates';
import {tooltipFormatter} from 'sentry/utils/discover/charts';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {aggregateOutputType} from 'sentry/utils/discover/fields';
import type {QueryError} from 'sentry/utils/discover/genericDiscoverQuery';
import {getDynamicText} from 'sentry/utils/getDynamicText';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/statusBreakdown.tsx b/static/app/views/performance/transactionSummary/transactionOverview/statusBreakdown.tsx
index b93f15e88e028e..bf59b768619c58 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/statusBreakdown.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/statusBreakdown.tsx
@@ -13,7 +13,7 @@ import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
import {DiscoverQuery} from 'sentry/utils/discover/discoverQuery';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useNavigate} from 'sentry/utils/useNavigate';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/tagExplorer.spec.tsx b/static/app/views/performance/transactionSummary/transactionOverview/tagExplorer.spec.tsx
index cce3578031b522..0762bc730ea84a 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/tagExplorer.spec.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/tagExplorer.spec.tsx
@@ -5,7 +5,7 @@ import {initializeOrg} from 'sentry-test/initializeOrg';
import {render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
import {ProjectsStore} from 'sentry/stores/projectsStore';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {MEPSettingProvider} from 'sentry/utils/performance/contexts/metricsEnhancedSetting';
import {OrganizationContext} from 'sentry/views/organizationContext';
import {SpanOperationBreakdownFilter} from 'sentry/views/performance/transactionSummary/filter';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/tagExplorer.tsx b/static/app/views/performance/transactionSummary/transactionOverview/tagExplorer.tsx
index 027c6f81fd095d..44a548080526fa 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/tagExplorer.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/tagExplorer.tsx
@@ -17,7 +17,7 @@ import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {isFieldSortable} from 'sentry/utils/discover/eventView';
import {fieldAlignment} from 'sentry/utils/discover/fields';
import {formatPercentage} from 'sentry/utils/number/formatPercentage';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/trendChart/content.tsx b/static/app/views/performance/transactionSummary/transactionOverview/trendChart/content.tsx
index d61c730c9d2621..1afe06ed6b16ef 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/trendChart/content.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/trendChart/content.tsx
@@ -6,7 +6,7 @@ import {ErrorPanel} from 'sentry/components/charts/errorPanel';
import type {LineChartProps} from 'sentry/components/charts/lineChart';
import {LineChart} from 'sentry/components/charts/lineChart';
import ReleaseSeries from 'sentry/components/charts/releaseSeries';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
import {Placeholder} from 'sentry/components/placeholder';
import {IconWarning} from 'sentry/icons';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/trendChart/index.tsx b/static/app/views/performance/transactionSummary/transactionOverview/trendChart/index.tsx
index ce4d3bf6aec509..a9df39d2278e1e 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/trendChart/index.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/trendChart/index.tsx
@@ -2,7 +2,7 @@ import {Fragment} from 'react';
import {useTheme} from '@emotion/react';
import type {Query} from 'history';
-import EventsRequest from 'sentry/components/charts/eventsRequest';
+import {EventsRequest} from 'sentry/components/charts/eventsRequest';
import {HeaderTitleLegend} from 'sentry/components/charts/styles';
import {getInterval, getSeriesSelection} from 'sentry/components/charts/utils';
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
@@ -16,7 +16,7 @@ import type {
} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {getUtcToLocalDateObject} from 'sentry/utils/dates';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {DURATION_UNITS, SIZE_UNITS} from 'sentry/utils/discover/fieldRenderers';
import {getAggregateAlias} from 'sentry/utils/discover/fields';
import {useMetricsCardinalityContext} from 'sentry/utils/performance/contexts/metricsCardinality';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/userMiseryChart/index.tsx b/static/app/views/performance/transactionSummary/transactionOverview/userMiseryChart/index.tsx
index 7836bdff4750be..d0a5dae3a348ef 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/userMiseryChart/index.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/userMiseryChart/index.tsx
@@ -1,7 +1,7 @@
import {Fragment} from 'react';
import type {Query} from 'history';
-import EventsRequest from 'sentry/components/charts/eventsRequest';
+import {EventsRequest} from 'sentry/components/charts/eventsRequest';
import {HeaderTitleLegend} from 'sentry/components/charts/styles';
import {getInterval} from 'sentry/components/charts/utils';
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/userStats.tsx b/static/app/views/performance/transactionSummary/transactionOverview/userStats.tsx
index 18448b0b64f123..2d93f27b771463 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/userStats.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/userStats.tsx
@@ -10,7 +10,7 @@ import {UserMisery} from 'sentry/components/userMisery';
import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import {DemoTourElement, DemoTourStep} from 'sentry/utils/demoMode/demoTours';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {QueryError} from 'sentry/utils/discover/genericDiscoverQuery';
import {WebVital} from 'sentry/utils/fields';
import {useMetricsCardinalityContext} from 'sentry/utils/performance/contexts/metricsCardinality';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/utils.tsx b/static/app/views/performance/transactionSummary/transactionOverview/utils.tsx
index b820d4b88287dd..d3bc30eaf3a229 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/utils.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/utils.tsx
@@ -1,7 +1,7 @@
import type {Location} from 'history';
import type {Organization} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {isAggregateField} from 'sentry/utils/discover/fields';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import type {MetricsCardinalityContext} from 'sentry/utils/performance/contexts/metricsCardinality';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/vitalsChart/content.tsx b/static/app/views/performance/transactionSummary/transactionOverview/vitalsChart/content.tsx
index df91bca14ed8e5..3d3e6e6cd2b210 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/vitalsChart/content.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/vitalsChart/content.tsx
@@ -6,7 +6,7 @@ import {ErrorPanel} from 'sentry/components/charts/errorPanel';
import type {LineChartProps} from 'sentry/components/charts/lineChart';
import {LineChart} from 'sentry/components/charts/lineChart';
import ReleaseSeries from 'sentry/components/charts/releaseSeries';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
import {Placeholder} from 'sentry/components/placeholder';
import {IconWarning} from 'sentry/icons';
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/vitalsChart/index.tsx b/static/app/views/performance/transactionSummary/transactionOverview/vitalsChart/index.tsx
index dd805097e08641..5036e6a8bee43a 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/vitalsChart/index.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/vitalsChart/index.tsx
@@ -2,7 +2,7 @@ import {Fragment} from 'react';
import {useTheme} from '@emotion/react';
import type {Query} from 'history';
-import EventsRequest from 'sentry/components/charts/eventsRequest';
+import {EventsRequest} from 'sentry/components/charts/eventsRequest';
import {HeaderTitleLegend} from 'sentry/components/charts/styles';
import {getInterval, getSeriesSelection} from 'sentry/components/charts/utils';
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
diff --git a/static/app/views/performance/transactionSummary/transactionReplays/index.spec.tsx b/static/app/views/performance/transactionSummary/transactionReplays/index.spec.tsx
index c59e03c0a959b1..7c71ab35ad39b0 100644
--- a/static/app/views/performance/transactionSummary/transactionReplays/index.spec.tsx
+++ b/static/app/views/performance/transactionSummary/transactionReplays/index.spec.tsx
@@ -13,7 +13,7 @@ import {
SPAN_OP_RELATIVE_BREAKDOWN_FIELD,
} from 'sentry/utils/discover/fields';
import TransactionSummaryLayout from 'sentry/views/performance/transactionSummary/layout';
-import TransactionSummaryTab from 'sentry/views/performance/transactionSummary/tabs';
+import {Tab as TransactionSummaryTab} from 'sentry/views/performance/transactionSummary/tabs';
import TransactionReplays from 'sentry/views/performance/transactionSummary/transactionReplays';
type InitializeOrgProps = {
diff --git a/static/app/views/performance/transactionSummary/transactionReplays/transactionReplays.tsx b/static/app/views/performance/transactionSummary/transactionReplays/transactionReplays.tsx
index 2a93a4931a1e78..c9fc699db34bbd 100644
--- a/static/app/views/performance/transactionSummary/transactionReplays/transactionReplays.tsx
+++ b/static/app/views/performance/transactionSummary/transactionReplays/transactionReplays.tsx
@@ -20,7 +20,7 @@ import {
} from 'sentry/components/replays/table/replayTableColumns';
import {usePlaylistQuery} from 'sentry/components/replays/usePlaylistQuery';
import type {Organization} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {useReplayList} from 'sentry/utils/replays/hooks/useReplayList';
import {useLocation} from 'sentry/utils/useLocation';
import {useMedia} from 'sentry/utils/useMedia';
diff --git a/static/app/views/performance/transactionSummary/transactionReplays/useReplaysFromTransaction.tsx b/static/app/views/performance/transactionSummary/transactionReplays/useReplaysFromTransaction.tsx
index 7f60ca002dc61b..aec423f35ac60f 100644
--- a/static/app/views/performance/transactionSummary/transactionReplays/useReplaysFromTransaction.tsx
+++ b/static/app/views/performance/transactionSummary/transactionReplays/useReplaysFromTransaction.tsx
@@ -4,7 +4,7 @@ import type {Location} from 'history';
import {DEFAULT_REPLAY_LIST_SORT} from 'sentry/components/replays/table/useReplayTableSort';
import type {Organization} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {doDiscoverQuery} from 'sentry/utils/discover/genericDiscoverQuery';
import {decodeScalar} from 'sentry/utils/queryString';
import {useApi} from 'sentry/utils/useApi';
diff --git a/static/app/views/performance/transactionSummary/transactionReplays/utils.ts b/static/app/views/performance/transactionSummary/transactionReplays/utils.ts
index 3de026ebefd4a3..4579d357714c7d 100644
--- a/static/app/views/performance/transactionSummary/transactionReplays/utils.ts
+++ b/static/app/views/performance/transactionSummary/transactionReplays/utils.ts
@@ -1,7 +1,7 @@
import type {Location, Query} from 'history';
import type {Organization} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {
SPAN_OP_BREAKDOWN_FIELDS,
SPAN_OP_RELATIVE_BREAKDOWN_FIELD,
diff --git a/static/app/views/performance/transactionSummary/transactionSummaryContext.tsx b/static/app/views/performance/transactionSummary/transactionSummaryContext.tsx
index ac369185c55c72..1ba032e99717b5 100644
--- a/static/app/views/performance/transactionSummary/transactionSummaryContext.tsx
+++ b/static/app/views/performance/transactionSummary/transactionSummaryContext.tsx
@@ -2,7 +2,7 @@ import {createContext, useContext} from 'react';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {TransactionThresholdMetric} from 'sentry/views/performance/transactionSummary/transactionThresholdModal';
export type TransactionSummaryContext = {
diff --git a/static/app/views/performance/transactionSummary/transactionTags/content.tsx b/static/app/views/performance/transactionSummary/transactionTags/content.tsx
index fd8bb15cfa4639..7c6e86788a12de 100644
--- a/static/app/views/performance/transactionSummary/transactionTags/content.tsx
+++ b/static/app/views/performance/transactionSummary/transactionTags/content.tsx
@@ -20,7 +20,7 @@ import {DataCategory} from 'sentry/types/core';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {TableData} from 'sentry/utils/performance/segmentExplorer/segmentExplorerQuery';
import {SegmentExplorerQuery} from 'sentry/utils/performance/segmentExplorer/segmentExplorerQuery';
import {decodeScalar} from 'sentry/utils/queryString';
diff --git a/static/app/views/performance/transactionSummary/transactionTags/index.spec.tsx b/static/app/views/performance/transactionSummary/transactionTags/index.spec.tsx
index 76d303616b5331..0e342424166b87 100644
--- a/static/app/views/performance/transactionSummary/transactionTags/index.spec.tsx
+++ b/static/app/views/performance/transactionSummary/transactionTags/index.spec.tsx
@@ -6,7 +6,7 @@ import {selectEvent} from 'sentry-test/selectEvent';
import {ProjectsStore} from 'sentry/stores/projectsStore';
import TransactionSummaryLayout from 'sentry/views/performance/transactionSummary/layout';
-import TransactionSummaryTab from 'sentry/views/performance/transactionSummary/tabs';
+import {Tab as TransactionSummaryTab} from 'sentry/views/performance/transactionSummary/tabs';
import TransactionTags from 'sentry/views/performance/transactionSummary/transactionTags';
const TEST_RELEASE_NAME = 'test-project@1.0.0';
diff --git a/static/app/views/performance/transactionSummary/transactionTags/tagValueTable.tsx b/static/app/views/performance/transactionSummary/transactionTags/tagValueTable.tsx
index ec44b1fecdf214..8ac22871da800b 100644
--- a/static/app/views/performance/transactionSummary/transactionTags/tagValueTable.tsx
+++ b/static/app/views/performance/transactionSummary/transactionTags/tagValueTable.tsx
@@ -15,7 +15,7 @@ import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {trackAnalytics} from 'sentry/utils/analytics';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {fieldAlignment} from 'sentry/utils/discover/fields';
import {formatPercentage} from 'sentry/utils/number/formatPercentage';
import type {
diff --git a/static/app/views/performance/transactionSummary/transactionTags/tagsDisplay.tsx b/static/app/views/performance/transactionSummary/transactionTags/tagsDisplay.tsx
index b74fe375f4a20a..e813adab31edda 100644
--- a/static/app/views/performance/transactionSummary/transactionTags/tagsDisplay.tsx
+++ b/static/app/views/performance/transactionSummary/transactionTags/tagsDisplay.tsx
@@ -5,7 +5,7 @@ import type {CursorHandler} from 'sentry/components/pagination';
import type {GridColumnOrder} from 'sentry/components/tables/gridEditable';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {SegmentExplorerQuery} from 'sentry/utils/performance/segmentExplorer/segmentExplorerQuery';
import {TagKeyHistogramQuery} from 'sentry/utils/performance/segmentExplorer/tagKeyHistogramQuery';
import {decodeScalar, decodeSorts} from 'sentry/utils/queryString';
diff --git a/static/app/views/performance/transactionSummary/transactionTags/tagsHeatMap.tsx b/static/app/views/performance/transactionSummary/transactionTags/tagsHeatMap.tsx
index a6c2ff17989dc7..ae7ef1f8ab7e56 100644
--- a/static/app/views/performance/transactionSummary/transactionTags/tagsHeatMap.tsx
+++ b/static/app/views/performance/transactionSummary/transactionTags/tagsHeatMap.tsx
@@ -14,7 +14,7 @@ import {Flex} from '@sentry/scraps/layout';
import {HeatMapChart} from 'sentry/components/charts/heatMapChart';
import {HeaderTitleLegend} from 'sentry/components/charts/styles';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {MenuItem} from 'sentry/components/menuItem';
@@ -29,7 +29,7 @@ import type {ReactEchartsRef, Series} from 'sentry/types/echarts';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {axisLabelFormatter} from 'sentry/utils/discover/charts';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {generateLinkToEventInTraceView} from 'sentry/utils/discover/urls';
import {formatAbbreviatedNumber} from 'sentry/utils/formatters';
import {getDynamicText} from 'sentry/utils/getDynamicText';
@@ -41,7 +41,7 @@ import {TagTransactionsQuery} from 'sentry/utils/performance/segmentExplorer/tag
import {decodeScalar} from 'sentry/utils/queryString';
import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters';
import {TraceViewSources} from 'sentry/views/performance/newTraceDetails/traceHeader/breadcrumbs';
-import Tab from 'sentry/views/performance/transactionSummary/tabs';
+import {Tab} from 'sentry/views/performance/transactionSummary/tabs';
import {eventsRouteWithQuery} from 'sentry/views/performance/transactionSummary/transactionEvents/utils';
import {getPerformanceDuration} from 'sentry/views/performance/utils/getPerformanceDuration';
diff --git a/static/app/views/performance/transactionSummary/transactionTags/utils.tsx b/static/app/views/performance/transactionSummary/transactionTags/utils.tsx
index c024e72e94cd9f..1f15e878ef1979 100644
--- a/static/app/views/performance/transactionSummary/transactionTags/utils.tsx
+++ b/static/app/views/performance/transactionSummary/transactionTags/utils.tsx
@@ -2,7 +2,7 @@ import type {Location, Query} from 'history';
import type {Organization} from 'sentry/types/organization';
import {trackAnalytics} from 'sentry/utils/analytics';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {decodeScalar} from 'sentry/utils/queryString';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import type {DomainView} from 'sentry/views/insights/pages/useFilters';
diff --git a/static/app/views/performance/transactionSummary/transactionThresholdButton.spec.tsx b/static/app/views/performance/transactionSummary/transactionThresholdButton.spec.tsx
index 9ef6cca3616427..97b20acd6c52d6 100644
--- a/static/app/views/performance/transactionSummary/transactionThresholdButton.spec.tsx
+++ b/static/app/views/performance/transactionSummary/transactionThresholdButton.spec.tsx
@@ -11,7 +11,7 @@ import {
import {ProjectsStore} from 'sentry/stores/projectsStore';
import type {Organization} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import TransactionThresholdButton from 'sentry/views/performance/transactionSummary/transactionThresholdButton';
function renderComponent(
diff --git a/static/app/views/performance/transactionSummary/transactionThresholdButton.tsx b/static/app/views/performance/transactionSummary/transactionThresholdButton.tsx
index 84a85c28193f93..6718cb0bb18346 100644
--- a/static/app/views/performance/transactionSummary/transactionThresholdButton.tsx
+++ b/static/app/views/performance/transactionSummary/transactionThresholdButton.tsx
@@ -10,7 +10,7 @@ import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {withApi} from 'sentry/utils/withApi';
import {withProjects} from 'sentry/utils/withProjects';
diff --git a/static/app/views/performance/transactionSummary/transactionThresholdModal.spec.tsx b/static/app/views/performance/transactionSummary/transactionThresholdModal.spec.tsx
index afb4dea1de0c03..7f08d9753220c9 100644
--- a/static/app/views/performance/transactionSummary/transactionThresholdModal.spec.tsx
+++ b/static/app/views/performance/transactionSummary/transactionThresholdModal.spec.tsx
@@ -12,7 +12,7 @@ import {
} from 'sentry/components/globalModal/components';
import {ProjectsStore} from 'sentry/stores/projectsStore';
import type {Organization} from 'sentry/types/organization';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import TransactionThresholdModal, {
TransactionThresholdMetric,
} from 'sentry/views/performance/transactionSummary/transactionThresholdModal';
diff --git a/static/app/views/performance/transactionSummary/transactionThresholdModal.tsx b/static/app/views/performance/transactionSummary/transactionThresholdModal.tsx
index 5f0e0ec95caee8..3a4051edcbcdfe 100644
--- a/static/app/views/performance/transactionSummary/transactionThresholdModal.tsx
+++ b/static/app/views/performance/transactionSummary/transactionThresholdModal.tsx
@@ -16,7 +16,7 @@ import {t, tct} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {withApi} from 'sentry/utils/withApi';
import {withProjects} from 'sentry/utils/withProjects';
diff --git a/static/app/views/performance/transactionSummary/useEventViewProject.ts b/static/app/views/performance/transactionSummary/useEventViewProject.ts
index 2dbf8b2ca49a7c..faef468a8afcfc 100644
--- a/static/app/views/performance/transactionSummary/useEventViewProject.ts
+++ b/static/app/views/performance/transactionSummary/useEventViewProject.ts
@@ -1,7 +1,7 @@
import {useMemo} from 'react';
import type {Project} from 'sentry/types/project';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
export function useEventViewProject(
projects: Project[],
diff --git a/static/app/views/performance/trends/chart.tsx b/static/app/views/performance/trends/chart.tsx
index 34fd1b22d79b08..b5011fef3a5c24 100644
--- a/static/app/views/performance/trends/chart.tsx
+++ b/static/app/views/performance/trends/chart.tsx
@@ -4,7 +4,7 @@ import type {LegendComponentOption, LineSeriesOption} from 'echarts';
import ChartZoom from 'sentry/components/charts/chartZoom';
import type {LineChartProps} from 'sentry/components/charts/lineChart';
import {LineChart} from 'sentry/components/charts/lineChart';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
import type {Project} from 'sentry/types/project';
diff --git a/static/app/views/performance/trends/types.tsx b/static/app/views/performance/trends/types.tsx
index 439e22d85401df..764b368dbfb580 100644
--- a/static/app/views/performance/trends/types.tsx
+++ b/static/app/views/performance/trends/types.tsx
@@ -3,8 +3,7 @@ import type moment from 'moment-timezone';
import type {EventQuery} from 'sentry/actionCreators/events';
import type {EventsStatsData} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
-import type {LocationQuery} from 'sentry/utils/discover/eventView';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView, LocationQuery} from 'sentry/utils/discover/eventView';
export type TrendView = EventView & {
middle?: string;
diff --git a/static/app/views/performance/types.tsx b/static/app/views/performance/types.tsx
index e08b3b7cde191c..cce31cd684b333 100644
--- a/static/app/views/performance/types.tsx
+++ b/static/app/views/performance/types.tsx
@@ -1,4 +1,4 @@
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {QUERY_KEYS} from './utils';
diff --git a/static/app/views/performance/utils/index.tsx b/static/app/views/performance/utils/index.tsx
index 1efac3f321fd3d..39c5877b50528a 100644
--- a/static/app/views/performance/utils/index.tsx
+++ b/static/app/views/performance/utils/index.tsx
@@ -14,7 +14,7 @@ import type {ReleaseProject} from 'sentry/types/release';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
import {toArray} from 'sentry/utils/array/toArray';
import type {EventData} from 'sentry/utils/discover/eventView';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {TRACING_FIELDS} from 'sentry/utils/discover/fields';
import {SavedQueryDatasets} from 'sentry/utils/discover/types';
import {statsPeriodToDays} from 'sentry/utils/duration/statsPeriodToDays';
diff --git a/static/app/views/performance/vitalDetail/vitalInfo.tsx b/static/app/views/performance/vitalDetail/vitalInfo.tsx
index 5e97507043ffe6..2368c5a9d2af94 100644
--- a/static/app/views/performance/vitalDetail/vitalInfo.tsx
+++ b/static/app/views/performance/vitalDetail/vitalInfo.tsx
@@ -2,7 +2,7 @@ import type {Location} from 'history';
import type {Organization} from 'sentry/types/organization';
import {toArray} from 'sentry/utils/array/toArray';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import type {WebVital} from 'sentry/utils/fields';
import {VitalsCardsDiscoverQuery as VitalsCardDiscoverQuery} from 'sentry/utils/performance/vitals/vitalsCardsDiscoverQuery';
import {VitalBar} from 'sentry/views/performance/landing/vitalsCards';
diff --git a/static/app/views/preprod/components/preprodQuotaAlert.tsx b/static/app/views/preprod/components/preprodQuotaAlert.tsx
index 882cbc7e7f1127..9e1f6e6a545faa 100644
--- a/static/app/views/preprod/components/preprodQuotaAlert.tsx
+++ b/static/app/views/preprod/components/preprodQuotaAlert.tsx
@@ -1,6 +1,6 @@
import {Alert} from '@sentry/scraps/alert';
-import ExternalLink from 'sentry/components/links/externalLink';
+import {ExternalLink} from 'sentry/components/links/externalLink';
import {t, tct} from 'sentry/locale';
import {getApiUrl} from 'sentry/utils/api/getApiUrl';
import {useApiQuery} from 'sentry/utils/queryClient';
diff --git a/static/app/views/profiling/profileSummary/index.tsx b/static/app/views/profiling/profileSummary/index.tsx
index ba3c1557534642..1e56955c2e3f31 100644
--- a/static/app/views/profiling/profileSummary/index.tsx
+++ b/static/app/views/profiling/profileSummary/index.tsx
@@ -11,7 +11,7 @@ import {TabList, Tabs} from '@sentry/scraps/tabs';
import {Count} from 'sentry/components/count';
import {DateTime} from 'sentry/components/dateTime';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {FeedbackButton} from 'sentry/components/feedbackButton/feedbackButton';
import {IdBadge} from 'sentry/components/idBadge';
import * as Layout from 'sentry/components/layouts/thirds';
@@ -37,7 +37,7 @@ import {DataCategory} from 'sentry/types/core';
import type {Project} from 'sentry/types/project';
import type {DeepPartial} from 'sentry/types/utils';
import {defined} from 'sentry/utils';
-import type EventView from 'sentry/utils/discover/eventView';
+import type {EventView} from 'sentry/utils/discover/eventView';
import {isAggregateField} from 'sentry/utils/discover/fields';
import type {CanvasScheduler} from 'sentry/utils/profiling/canvasScheduler';
import {
diff --git a/static/app/views/projectDetail/charts/projectBaseEventsChart.tsx b/static/app/views/projectDetail/charts/projectBaseEventsChart.tsx
index a1f7f08c1dd0c0..81f065d4183b4c 100644
--- a/static/app/views/projectDetail/charts/projectBaseEventsChart.tsx
+++ b/static/app/views/projectDetail/charts/projectBaseEventsChart.tsx
@@ -4,7 +4,7 @@ import isEqual from 'lodash/isEqual';
import {fetchTotalCount} from 'sentry/actionCreators/events';
import type {EventsChartProps} from 'sentry/components/charts/eventsChart';
-import EventsChart from 'sentry/components/charts/eventsChart';
+import {EventsChart} from 'sentry/components/charts/eventsChart';
import {HeaderTitleLegend} from 'sentry/components/charts/styles';
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
import {QuestionTooltip} from 'sentry/components/questionTooltip';
diff --git a/static/app/views/projectDetail/charts/projectBaseSessionsChart.tsx b/static/app/views/projectDetail/charts/projectBaseSessionsChart.tsx
index 4ecc1e1806caa6..e553722aa39fff 100644
--- a/static/app/views/projectDetail/charts/projectBaseSessionsChart.tsx
+++ b/static/app/views/projectDetail/charts/projectBaseSessionsChart.tsx
@@ -14,7 +14,7 @@ import {LineChart} from 'sentry/components/charts/lineChart';
import ReleaseSeries from 'sentry/components/charts/releaseSeries';
import {StackedAreaChart} from 'sentry/components/charts/stackedAreaChart';
import {HeaderTitleLegend} from 'sentry/components/charts/styles';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
import {RELEASE_LINES_THRESHOLD} from 'sentry/components/charts/utils';
import {QuestionTooltip} from 'sentry/components/questionTooltip';
diff --git a/static/app/views/projectDetail/missingFeatureButtons/missingPerformanceButtons.tsx b/static/app/views/projectDetail/missingFeatureButtons/missingPerformanceButtons.tsx
index 7981780856582f..a671fa5185dd32 100644
--- a/static/app/views/projectDetail/missingFeatureButtons/missingPerformanceButtons.tsx
+++ b/static/app/views/projectDetail/missingFeatureButtons/missingPerformanceButtons.tsx
@@ -3,7 +3,7 @@ import {Grid} from '@sentry/scraps/layout';
import {navigateTo} from 'sentry/actionCreators/navigation';
import Feature from 'sentry/components/acl/feature';
-import FeatureTourModal from 'sentry/components/modals/featureTourModal';
+import {FeatureTourModal} from 'sentry/components/modals/featureTourModal';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import {t} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
diff --git a/static/app/views/projectDetail/missingFeatureButtons/missingReleasesButtons.tsx b/static/app/views/projectDetail/missingFeatureButtons/missingReleasesButtons.tsx
index d56e59d4b5f739..d8054004af47f7 100644
--- a/static/app/views/projectDetail/missingFeatureButtons/missingReleasesButtons.tsx
+++ b/static/app/views/projectDetail/missingFeatureButtons/missingReleasesButtons.tsx
@@ -1,7 +1,7 @@
import {Button, LinkButton} from '@sentry/scraps/button';
import {Grid} from '@sentry/scraps/layout';
-import FeatureTourModal from 'sentry/components/modals/featureTourModal';
+import {FeatureTourModal} from 'sentry/components/modals/featureTourModal';
import {releaseHealth} from 'sentry/data/platformCategories';
import {t} from 'sentry/locale';
import {ConfigStore} from 'sentry/stores/configStore';
diff --git a/static/app/views/projectDetail/projectDetail.tsx b/static/app/views/projectDetail/projectDetail.tsx
index 71e8c2331608cc..d1bb5ef51b36b7 100644
--- a/static/app/views/projectDetail/projectDetail.tsx
+++ b/static/app/views/projectDetail/projectDetail.tsx
@@ -11,7 +11,7 @@ import {fetchTagValues} from 'sentry/actionCreators/tags';
import Feature from 'sentry/components/acl/feature';
import {Breadcrumbs} from 'sentry/components/breadcrumbs';
import {CreateAlertButton} from 'sentry/components/createAlertButton';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {FeedbackButton} from 'sentry/components/feedbackButton/feedbackButton';
import {IdBadge} from 'sentry/components/idBadge';
import * as Layout from 'sentry/components/layouts/thirds';
diff --git a/static/app/views/projectDetail/projectIssues.tsx b/static/app/views/projectDetail/projectIssues.tsx
index fa57a756506815..557e4246bef3e8 100644
--- a/static/app/views/projectDetail/projectIssues.tsx
+++ b/static/app/views/projectDetail/projectIssues.tsx
@@ -26,7 +26,7 @@ import {SavedQueryDatasets} from 'sentry/utils/discover/types';
import {decodeScalar} from 'sentry/utils/queryString';
import {appendQueryDatasetParam} from 'sentry/views/dashboards/utils';
import {makeDiscoverPathname} from 'sentry/views/discover/pathnames';
-import NoGroupsHandler from 'sentry/views/issueList/noGroupsHandler';
+import {NoGroupsHandler} from 'sentry/views/issueList/noGroupsHandler';
enum IssuesType {
NEW = 'new',
diff --git a/static/app/views/releases/detail/overview/index.tsx b/static/app/views/releases/detail/overview/index.tsx
index 627f240146ae7d..93a351917936b3 100644
--- a/static/app/views/releases/detail/overview/index.tsx
+++ b/static/app/views/releases/detail/overview/index.tsx
@@ -28,7 +28,7 @@ import {SessionFieldWithOperation} from 'sentry/types/organization';
import {getUtcDateString} from 'sentry/utils/dates';
import {DemoTourElement, DemoTourStep} from 'sentry/utils/demoMode/demoTours';
import type {TableDataRow} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {decodeScalar} from 'sentry/utils/queryString';
import {useApi} from 'sentry/utils/useApi';
import {useLocation} from 'sentry/utils/useLocation';
diff --git a/static/app/views/releases/detail/overview/releaseComparisonChart/index.tsx b/static/app/views/releases/detail/overview/releaseComparisonChart/index.tsx
index c3e5eba4f3aa3f..ee0f8caf5b21a5 100644
--- a/static/app/views/releases/detail/overview/releaseComparisonChart/index.tsx
+++ b/static/app/views/releases/detail/overview/releaseComparisonChart/index.tsx
@@ -12,7 +12,7 @@ import type {Client} from 'sentry/api';
import {ErrorPanel} from 'sentry/components/charts/errorPanel';
import {ChartContainer} from 'sentry/components/charts/styles';
import {Count} from 'sentry/components/count';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {NotAvailable} from 'sentry/components/notAvailable';
import {extractSelectionParameters} from 'sentry/components/pageFilters/parse';
import {Panel} from 'sentry/components/panels/panel';
diff --git a/static/app/views/releases/detail/overview/releaseComparisonChart/releaseEventsChart.tsx b/static/app/views/releases/detail/overview/releaseComparisonChart/releaseEventsChart.tsx
index b63945bc59c102..f2c90bdf2751ba 100644
--- a/static/app/views/releases/detail/overview/releaseComparisonChart/releaseEventsChart.tsx
+++ b/static/app/views/releases/detail/overview/releaseComparisonChart/releaseEventsChart.tsx
@@ -3,8 +3,8 @@ import {useTheme} from '@emotion/react';
import type {ToolboxComponentOption} from 'echarts';
import {Client} from 'sentry/api';
-import EventsChart from 'sentry/components/charts/eventsChart';
-import EventsRequest from 'sentry/components/charts/eventsRequest';
+import {EventsChart} from 'sentry/components/charts/eventsChart';
+import {EventsRequest} from 'sentry/components/charts/eventsRequest';
import {HeaderTitleLegend, HeaderValue} from 'sentry/components/charts/styles';
import {getInterval} from 'sentry/components/charts/utils';
import {QuestionTooltip} from 'sentry/components/questionTooltip';
@@ -13,7 +13,7 @@ import type {Organization} from 'sentry/types/organization';
import type {ReleaseProject, ReleaseWithHealth} from 'sentry/types/release';
import {ReleaseComparisonChartType} from 'sentry/types/release';
import {tooltipFormatter} from 'sentry/utils/discover/charts';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {aggregateOutputType} from 'sentry/utils/discover/fields';
import {DiscoverDatasets} from 'sentry/utils/discover/types';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
diff --git a/static/app/views/releases/detail/overview/releaseComparisonChart/releaseSessionsChart.tsx b/static/app/views/releases/detail/overview/releaseComparisonChart/releaseSessionsChart.tsx
index ce7750bad2d1a4..518456c0be6e7b 100644
--- a/static/app/views/releases/detail/overview/releaseComparisonChart/releaseSessionsChart.tsx
+++ b/static/app/views/releases/detail/overview/releaseComparisonChart/releaseSessionsChart.tsx
@@ -9,7 +9,7 @@ import {AreaChart} from 'sentry/components/charts/areaChart';
import ChartZoom from 'sentry/components/charts/chartZoom';
import {StackedAreaChart} from 'sentry/components/charts/stackedAreaChart';
import {HeaderTitleLegend, HeaderValue} from 'sentry/components/charts/styles';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
import {QuestionTooltip} from 'sentry/components/questionTooltip';
import {t} from 'sentry/locale';
diff --git a/static/app/views/releases/detail/overview/sidebar/releaseAdoption.tsx b/static/app/views/releases/detail/overview/sidebar/releaseAdoption.tsx
index d578eecee416fa..8d703817ce644c 100644
--- a/static/app/views/releases/detail/overview/sidebar/releaseAdoption.tsx
+++ b/static/app/views/releases/detail/overview/sidebar/releaseAdoption.tsx
@@ -9,9 +9,9 @@ import ChartZoom from 'sentry/components/charts/chartZoom';
import {ErrorPanel} from 'sentry/components/charts/errorPanel';
import type {LineChartProps} from 'sentry/components/charts/lineChart';
import {LineChart} from 'sentry/components/charts/lineChart';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {NotAvailable} from 'sentry/components/notAvailable';
import {QuestionTooltip} from 'sentry/components/questionTooltip';
import * as SidebarSection from 'sentry/components/sidebarSection';
diff --git a/static/app/views/releases/drawer/releasesDrawerDetails.tsx b/static/app/views/releases/drawer/releasesDrawerDetails.tsx
index 10e9b72efb12b1..ad259c16837646 100644
--- a/static/app/views/releases/drawer/releasesDrawerDetails.tsx
+++ b/static/app/views/releases/drawer/releasesDrawerDetails.tsx
@@ -7,7 +7,7 @@ import {Flex, Stack} from '@sentry/scraps/layout';
import {Link} from '@sentry/scraps/link';
import {Select} from '@sentry/scraps/select';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {
EventDrawerBody,
EventDrawerContainer,
diff --git a/static/app/views/releases/list/mobileBuildsChart.tsx b/static/app/views/releases/list/mobileBuildsChart.tsx
index bbd11a2e932eb4..3fb7e2619f5a25 100644
--- a/static/app/views/releases/list/mobileBuildsChart.tsx
+++ b/static/app/views/releases/list/mobileBuildsChart.tsx
@@ -8,7 +8,7 @@ import {Container} from '@sentry/scraps/layout';
import {OverlayTrigger} from '@sentry/scraps/overlayTrigger';
import {LineChart} from 'sentry/components/charts/lineChart';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {Panel} from 'sentry/components/panels/panel';
import {PanelBody} from 'sentry/components/panels/panelBody';
import {Placeholder} from 'sentry/components/placeholder';
diff --git a/static/app/views/releases/list/releasesAdoptionChart.tsx b/static/app/views/releases/list/releasesAdoptionChart.tsx
index 9c46882558dad9..8802e978db757d 100644
--- a/static/app/views/releases/list/releasesAdoptionChart.tsx
+++ b/static/app/views/releases/list/releasesAdoptionChart.tsx
@@ -11,14 +11,14 @@ import {Flex} from '@sentry/scraps/layout';
import ChartZoom from 'sentry/components/charts/chartZoom';
import {LineChart} from 'sentry/components/charts/lineChart';
-import SessionsRequest from 'sentry/components/charts/sessionsRequest';
+import {SessionsRequest} from 'sentry/components/charts/sessionsRequest';
import {
HeaderTitleLegend,
InlineContainer,
SectionHeading,
SectionValue,
} from 'sentry/components/charts/styles';
-import TransitionChart from 'sentry/components/charts/transitionChart';
+import {TransitionChart} from 'sentry/components/charts/transitionChart';
import {TransparentLoadingMask} from 'sentry/components/charts/transparentLoadingMask';
import {
getDiffInMinutes,
diff --git a/static/app/views/replays/detail/console/consoleLogRow.tsx b/static/app/views/replays/detail/console/consoleLogRow.tsx
index 8b387e483c8099..90133f26ba1c41 100644
--- a/static/app/views/replays/detail/console/consoleLogRow.tsx
+++ b/static/app/views/replays/detail/console/consoleLogRow.tsx
@@ -4,7 +4,7 @@ import classNames from 'classnames';
import {Tooltip} from '@sentry/scraps/tooltip';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {IconClose, IconInfo, IconWarning} from 'sentry/icons';
import {BreadcrumbLevelType} from 'sentry/types/breadcrumbs';
import type {useCrumbHandlers} from 'sentry/utils/replays/hooks/useCrumbHandlers';
diff --git a/static/app/views/replays/detail/header/replayDetailsPageBreadcrumbs.tsx b/static/app/views/replays/detail/header/replayDetailsPageBreadcrumbs.tsx
index 032203baf1b1b6..9071adaaf542db 100644
--- a/static/app/views/replays/detail/header/replayDetailsPageBreadcrumbs.tsx
+++ b/static/app/views/replays/detail/header/replayDetailsPageBreadcrumbs.tsx
@@ -15,7 +15,7 @@ import {IconChevron, IconCopy, IconRefresh} from 'sentry/icons';
import {t} from 'sentry/locale';
import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {getShortEventId} from 'sentry/utils/events';
import type {useLoadReplayReader} from 'sentry/utils/replays/hooks/useLoadReplayReader';
import {useReplayPlaylist} from 'sentry/utils/replays/playback/providers/replayPlaylistProvider';
diff --git a/static/app/views/replays/detail/layout/replayLayout.tsx b/static/app/views/replays/detail/layout/replayLayout.tsx
index 7644ad8a2ef185..f525068e9df268 100644
--- a/static/app/views/replays/detail/layout/replayLayout.tsx
+++ b/static/app/views/replays/detail/layout/replayLayout.tsx
@@ -4,7 +4,7 @@ import styled from '@emotion/styled';
import {Stack} from '@sentry/scraps/layout';
import {TooltipContext} from '@sentry/scraps/tooltip';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {Placeholder} from 'sentry/components/placeholder';
import {ReplayController} from 'sentry/components/replays/replayController';
import {ReplayView} from 'sentry/components/replays/replayView';
diff --git a/static/app/views/replays/detail/trace/useReplayTraces.tsx b/static/app/views/replays/detail/trace/useReplayTraces.tsx
index 64a79e753a18ef..f20bd793c35a95 100644
--- a/static/app/views/replays/detail/trace/useReplayTraces.tsx
+++ b/static/app/views/replays/detail/trace/useReplayTraces.tsx
@@ -3,7 +3,7 @@ import type {Location} from 'history';
import {getTimeStampFromTableDateField, getUtcDateString} from 'sentry/utils/dates';
import type {TableData} from 'sentry/utils/discover/discoverQuery';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {doDiscoverQuery} from 'sentry/utils/discover/genericDiscoverQuery';
import type {ParsedHeader} from 'sentry/utils/parseLinkHeader';
import {parseLinkHeader} from 'sentry/utils/parseLinkHeader';
diff --git a/static/app/views/replays/selectors/exampleReplaysList.tsx b/static/app/views/replays/selectors/exampleReplaysList.tsx
index c701b321e36e23..b49af9304dab59 100644
--- a/static/app/views/replays/selectors/exampleReplaysList.tsx
+++ b/static/app/views/replays/selectors/exampleReplaysList.tsx
@@ -12,7 +12,7 @@ import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {ReplayBadge} from 'sentry/components/replays/replayBadge';
import {t} from 'sentry/locale';
import {trackAnalytics} from 'sentry/utils/analytics';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
import {getRouteStringFromRoutes} from 'sentry/utils/getRouteStringFromRoutes';
import {useReplayList} from 'sentry/utils/replays/hooks/useReplayList';
import {useOrganization} from 'sentry/utils/useOrganization';
diff --git a/static/app/views/settings/account/accountDetails.tsx b/static/app/views/settings/account/accountDetails.tsx
index 0224c911406c8a..16e067d19f8666 100644
--- a/static/app/views/settings/account/accountDetails.tsx
+++ b/static/app/views/settings/account/accountDetails.tsx
@@ -9,7 +9,7 @@ import {AvatarChooser} from 'sentry/components/avatarChooser';
import {LoadingError} from 'sentry/components/loadingError';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {SentryDocumentTitle} from 'sentry/components/sentryDocumentTitle';
-import languages from 'sentry/data/languages';
+import {languages} from 'sentry/data/languages';
import {timezoneOptions} from 'sentry/data/timezones';
import {t} from 'sentry/locale';
import {StacktraceOrder, type User} from 'sentry/types/user';
diff --git a/static/app/views/settings/components/dataScrubbing/modals/dataScrubFormModal.tsx b/static/app/views/settings/components/dataScrubbing/modals/dataScrubFormModal.tsx
index 6dec567b6438cb..86ac906cee94b7 100644
--- a/static/app/views/settings/components/dataScrubbing/modals/dataScrubFormModal.tsx
+++ b/static/app/views/settings/components/dataScrubbing/modals/dataScrubFormModal.tsx
@@ -45,7 +45,7 @@ import {
import {AttributeField} from './form/attributeField';
import {EventIdField} from './form/eventIdField';
-import SourceField from './form/sourceField';
+import {SourceField} from './form/sourceField';
import {ErrorType, handleError} from './handleError';
import {hasCaptureGroups, useSourceGroupData} from './utils';
diff --git a/static/app/views/settings/components/dataScrubbing/modals/form/sourceField.spec.tsx b/static/app/views/settings/components/dataScrubbing/modals/form/sourceField.spec.tsx
index c55ab2f009fe87..cb913076a734e4 100644
--- a/static/app/views/settings/components/dataScrubbing/modals/form/sourceField.spec.tsx
+++ b/static/app/views/settings/components/dataScrubbing/modals/form/sourceField.spec.tsx
@@ -1,6 +1,6 @@
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
-import SourceField from 'sentry/views/settings/components/dataScrubbing/modals/form/sourceField';
+import {SourceField} from 'sentry/views/settings/components/dataScrubbing/modals/form/sourceField';
import {
binarySuggestions,
unarySuggestions,
diff --git a/static/app/views/settings/components/dataScrubbing/modals/form/sourceField.tsx b/static/app/views/settings/components/dataScrubbing/modals/form/sourceField.tsx
index ad26caf7e25a35..f7a557d0b208df 100644
--- a/static/app/views/settings/components/dataScrubbing/modals/form/sourceField.tsx
+++ b/static/app/views/settings/components/dataScrubbing/modals/form/sourceField.tsx
@@ -42,7 +42,7 @@ type State = {
suggestions: SourceSuggestion[];
};
-class SourceField extends Component {
+export class SourceField extends Component {
state: State = {
suggestions: [],
fieldValues: [],
@@ -451,8 +451,6 @@ class SourceField extends Component {
}
}
-export default SourceField;
-
const Wrapper = styled('div')<{hideCaret?: boolean}>`
position: relative;
width: 100%;
diff --git a/static/app/views/settings/organizationIntegrations/integrationAlertContainer.tsx b/static/app/views/settings/organizationIntegrations/integrationAlertContainer.tsx
index 9fd894e2853b5f..894c3444d24179 100644
--- a/static/app/views/settings/organizationIntegrations/integrationAlertContainer.tsx
+++ b/static/app/views/settings/organizationIntegrations/integrationAlertContainer.tsx
@@ -1,5 +1,5 @@
import styled from '@emotion/styled';
-export default styled('div')`
+export const AlertContainer = styled('div')`
padding: 0px ${p => p.theme.space['2xl']} 0px 68px;
`;
diff --git a/static/app/views/settings/organizationIntegrations/integrationRow.tsx b/static/app/views/settings/organizationIntegrations/integrationRow.tsx
index 552337d18f0603..3121f9b77c6a7a 100644
--- a/static/app/views/settings/organizationIntegrations/integrationRow.tsx
+++ b/static/app/views/settings/organizationIntegrations/integrationRow.tsx
@@ -22,7 +22,7 @@ import {
trackIntegrationAnalytics,
} from 'sentry/utils/integrationUtil';
-import AlertContainer from './integrationAlertContainer';
+import {AlertContainer} from './integrationAlertContainer';
import {IntegrationStatus} from './integrationStatus';
import {PluginDeprecationAlert} from './pluginDeprecationAlert';
diff --git a/static/app/views/settings/organizationRelay/modals/add/index.tsx b/static/app/views/settings/organizationRelay/modals/add/index.tsx
index d5041303cd53a5..997b5632e02a09 100644
--- a/static/app/views/settings/organizationRelay/modals/add/index.tsx
+++ b/static/app/views/settings/organizationRelay/modals/add/index.tsx
@@ -4,12 +4,12 @@ import {ExternalLink} from '@sentry/scraps/link';
import {List} from 'sentry/components/list';
import {t, tct} from 'sentry/locale';
-import ModalManager from 'sentry/views/settings/organizationRelay/modals/modalManager';
+import {ModalManager} from 'sentry/views/settings/organizationRelay/modals/modalManager';
import {Item} from './item';
import {Terminal} from './terminal';
-class Add extends ModalManager {
+export class Add extends ModalManager {
getTitle() {
return t('Register Key');
}
@@ -63,8 +63,6 @@ class Add extends ModalManager {
}
}
-export default Add;
-
const StyledList = styled(List)`
display: grid;
gap: ${p => p.theme.space['2xl']};
diff --git a/static/app/views/settings/organizationRelay/modals/edit.tsx b/static/app/views/settings/organizationRelay/modals/edit.tsx
index 43480582c905a2..5d3d2620f33646 100644
--- a/static/app/views/settings/organizationRelay/modals/edit.tsx
+++ b/static/app/views/settings/organizationRelay/modals/edit.tsx
@@ -1,7 +1,7 @@
import {t} from 'sentry/locale';
import type {Relay} from 'sentry/types/relay';
-import ModalManager from './modalManager';
+import {ModalManager} from './modalManager';
type Props = {
relay: Relay;
@@ -9,7 +9,7 @@ type Props = {
type State = ModalManager['state'];
-class Edit extends ModalManager {
+export class Edit extends ModalManager {
getDefaultState() {
return {
...super.getDefaultState(),
@@ -40,5 +40,3 @@ class Edit extends ModalManager {
return {trustedRelays};
}
}
-
-export default Edit;
diff --git a/static/app/views/settings/organizationRelay/modals/modalManager.tsx b/static/app/views/settings/organizationRelay/modals/modalManager.tsx
index b86693f70075cc..78dc32cdda2799 100644
--- a/static/app/views/settings/organizationRelay/modals/modalManager.tsx
+++ b/static/app/views/settings/organizationRelay/modals/modalManager.tsx
@@ -32,10 +32,10 @@ type State = {
values: Values;
};
-class DialogManager extends Component<
- P,
- S
-> {
+export class ModalManager<
+ P extends Props = Props,
+ S extends State = State,
+> extends Component
{
state = this.getDefaultState();
componentDidMount() {
@@ -236,5 +236,3 @@ class DialogManager
extends Co
);
}
}
-
-export default DialogManager;
diff --git a/static/app/views/settings/organizationRelay/relayWrapper.tsx b/static/app/views/settings/organizationRelay/relayWrapper.tsx
index f0ba87c1037a3d..2cfd23c1755c31 100644
--- a/static/app/views/settings/organizationRelay/relayWrapper.tsx
+++ b/static/app/views/settings/organizationRelay/relayWrapper.tsx
@@ -24,8 +24,8 @@ import {SettingsPageHeader} from 'sentry/views/settings/components/settingsPageH
import {TextBlock} from 'sentry/views/settings/components/text/textBlock';
import {OrganizationPermissionAlert} from 'sentry/views/settings/organization/organizationPermissionAlert';
-import Add from './modals/add';
-import Edit from './modals/edit';
+import {Add} from './modals/add';
+import {Edit} from './modals/edit';
import {EmptyState} from './emptyState';
import {List} from './list';
diff --git a/static/app/views/settings/project/projectFilters/groupTombstones.tsx b/static/app/views/settings/project/projectFilters/groupTombstones.tsx
index 0beba4d2b04762..c63689589d9d73 100644
--- a/static/app/views/settings/project/projectFilters/groupTombstones.tsx
+++ b/static/app/views/settings/project/projectFilters/groupTombstones.tsx
@@ -9,7 +9,7 @@ import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicato
import {Access} from 'sentry/components/acl/access';
import {Confirm} from 'sentry/components/confirm';
import {Count} from 'sentry/components/count';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {EventMessage} from 'sentry/components/events/eventMessage';
import {LoadingError} from 'sentry/components/loadingError';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
diff --git a/static/app/views/settings/project/projectOwnership/index.tsx b/static/app/views/settings/project/projectOwnership/index.tsx
index 95cb45d06f0908..235db6a1221f69 100644
--- a/static/app/views/settings/project/projectOwnership/index.tsx
+++ b/static/app/views/settings/project/projectOwnership/index.tsx
@@ -9,7 +9,7 @@ import {ExternalLink} from '@sentry/scraps/link';
import {closeModal, openEditOwnershipRules, openModal} from 'sentry/actionCreators/modal';
import {Access, hasEveryAccess} from 'sentry/components/acl/access';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {SentryDocumentTitle} from 'sentry/components/sentryDocumentTitle';
import {IconEdit} from 'sentry/icons';
diff --git a/static/app/views/settings/project/projectServiceHookDetails.tsx b/static/app/views/settings/project/projectServiceHookDetails.tsx
index 112e74bc61380c..73398b2c1efad1 100644
--- a/static/app/views/settings/project/projectServiceHookDetails.tsx
+++ b/static/app/views/settings/project/projectServiceHookDetails.tsx
@@ -9,7 +9,7 @@ import {
} from 'sentry/actionCreators/indicator';
import {MiniBarChart} from 'sentry/components/charts/miniBarChart';
import {EmptyMessage} from 'sentry/components/emptyMessage';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {FieldGroup} from 'sentry/components/forms/fieldGroup';
import {LoadingError} from 'sentry/components/loadingError';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
diff --git a/static/app/views/settings/projectSeer/index.tsx b/static/app/views/settings/projectSeer/index.tsx
index f9f0820f6a7f1a..f7a686fd914152 100644
--- a/static/app/views/settings/projectSeer/index.tsx
+++ b/static/app/views/settings/projectSeer/index.tsx
@@ -25,7 +25,7 @@ import {Form} from 'sentry/components/forms/form';
import JsonForm from 'sentry/components/forms/jsonForm';
import type {FieldObject, JsonFormObject} from 'sentry/components/forms/types';
import {HookOrDefault} from 'sentry/components/hookOrDefault';
-import ExternalLink from 'sentry/components/links/externalLink';
+import {ExternalLink} from 'sentry/components/links/externalLink';
import {NoAccess} from 'sentry/components/noAccess';
import {Placeholder} from 'sentry/components/placeholder';
import {SentryDocumentTitle} from 'sentry/components/sentryDocumentTitle';
diff --git a/static/gsAdmin/components/detailsPage.tsx b/static/gsAdmin/components/detailsPage.tsx
index 88c6f4f6a41aeb..70a4efc04a05ab 100644
--- a/static/gsAdmin/components/detailsPage.tsx
+++ b/static/gsAdmin/components/detailsPage.tsx
@@ -5,7 +5,7 @@ import {Tag, type TagProps} from '@sentry/scraps/badge';
import {Flex} from '@sentry/scraps/layout';
import {Tooltip} from '@sentry/scraps/tooltip';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {Panel} from 'sentry/components/panels/panel';
import {PanelHeader} from 'sentry/components/panels/panelHeader';
diff --git a/static/gsAdmin/components/forkCustomer.tsx b/static/gsAdmin/components/forkCustomer.tsx
index 8d9fbbfa13d0a8..0b87a82ef0c523 100644
--- a/static/gsAdmin/components/forkCustomer.tsx
+++ b/static/gsAdmin/components/forkCustomer.tsx
@@ -26,7 +26,7 @@ type State = {
/**
* Rendered as part of a openAdminConfirmModal call
*/
-class ForkCustomerAction extends Component {
+export class ForkCustomerAction extends Component {
state: State = {
regionUrl: '',
};
@@ -81,5 +81,3 @@ class ForkCustomerAction extends Component {
);
}
}
-
-export default ForkCustomerAction;
diff --git a/static/gsAdmin/components/provisionSubscriptionAction.tsx b/static/gsAdmin/components/provisionSubscriptionAction.tsx
index 14329a85e81a95..be2f0b71434a23 100644
--- a/static/gsAdmin/components/provisionSubscriptionAction.tsx
+++ b/static/gsAdmin/components/provisionSubscriptionAction.tsx
@@ -8,8 +8,8 @@ import {openModal} from 'sentry/actionCreators/modal';
import type {Client} from 'sentry/api';
import BooleanField from 'sentry/components/deprecatedforms/booleanField';
import {DateTimeField} from 'sentry/components/deprecatedforms/dateTimeField';
-import Form from 'sentry/components/deprecatedforms/form';
-import InputField from 'sentry/components/deprecatedforms/inputField';
+import {Form} from 'sentry/components/deprecatedforms/form';
+import {InputField} from 'sentry/components/deprecatedforms/inputField';
import NumberField, {
NumberField as NumberFieldNoContext,
} from 'sentry/components/deprecatedforms/numberField';
diff --git a/static/gsAdmin/components/sponsorshipAction.tsx b/static/gsAdmin/components/sponsorshipAction.tsx
index e2c8c892bd04a1..ceca1c08e87799 100644
--- a/static/gsAdmin/components/sponsorshipAction.tsx
+++ b/static/gsAdmin/components/sponsorshipAction.tsx
@@ -21,7 +21,7 @@ type State = {
/**
* Rendered as part of a openAdminConfirmModal call
*/
-class SponsorshipAction extends Component {
+export class SponsorshipAction extends Component {
state: State = {
sponsoredType: undefined,
};
@@ -80,5 +80,3 @@ class SponsorshipAction extends Component {
);
}
}
-
-export default SponsorshipAction;
diff --git a/static/gsAdmin/components/suspendAccountAction.tsx b/static/gsAdmin/components/suspendAccountAction.tsx
index f8d706978bd484..36096840919e86 100644
--- a/static/gsAdmin/components/suspendAccountAction.tsx
+++ b/static/gsAdmin/components/suspendAccountAction.tsx
@@ -21,7 +21,7 @@ type State = {
/**
* Rendered as part of a openAdminConfirmModal call
*/
-class SuspendAccountAction extends Component {
+export class SuspendAccountAction extends Component {
state: State = {
suspensionReason: null,
};
@@ -62,5 +62,3 @@ class SuspendAccountAction extends Component {
));
}
}
-
-export default SuspendAccountAction;
diff --git a/static/gsAdmin/components/trialSubscriptionAction.spec.tsx b/static/gsAdmin/components/trialSubscriptionAction.spec.tsx
index 6454636d3cc589..210a57636ac0c7 100644
--- a/static/gsAdmin/components/trialSubscriptionAction.spec.tsx
+++ b/static/gsAdmin/components/trialSubscriptionAction.spec.tsx
@@ -10,7 +10,7 @@ import {
} from 'sentry-test/reactTestingLibrary';
import {openAdminConfirmModal} from 'admin/components/adminConfirmationModal';
-import TrialSubscriptionAction from 'admin/components/trialSubscriptionAction';
+import {TrialSubscriptionAction} from 'admin/components/trialSubscriptionAction';
import {PlanTier} from 'getsentry/types';
describe('TrialSubscriptionAction', () => {
diff --git a/static/gsAdmin/components/trialSubscriptionAction.tsx b/static/gsAdmin/components/trialSubscriptionAction.tsx
index 9a699a897397f5..5ece6e33900a11 100644
--- a/static/gsAdmin/components/trialSubscriptionAction.tsx
+++ b/static/gsAdmin/components/trialSubscriptionAction.tsx
@@ -27,7 +27,7 @@ type State = {
/**
* Rendered as part of a openAdminConfirmModal call
*/
-class TrialSubscriptionAction extends Component {
+export class TrialSubscriptionAction extends Component {
state: State = {
trialDays:
this.props.subscription.isEnterpriseTrial || this.props.startEnterpriseTrial
@@ -143,5 +143,3 @@ class TrialSubscriptionAction extends Component {
);
}
}
-
-export default TrialSubscriptionAction;
diff --git a/static/gsAdmin/views/customerDetails.tsx b/static/gsAdmin/views/customerDetails.tsx
index 94efb4a7528abf..4269f88e614fc6 100644
--- a/static/gsAdmin/views/customerDetails.tsx
+++ b/static/gsAdmin/views/customerDetails.tsx
@@ -10,7 +10,7 @@ import {
addLoadingMessage,
addSuccessMessage,
} from 'sentry/actionCreators/indicator';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {LoadingError} from 'sentry/components/loadingError';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {ConfigStore} from 'sentry/stores/configStore';
@@ -62,17 +62,17 @@ import {openUpdateRetentionSettingsModal} from 'admin/components/customers/updat
import {deleteBillingMetricHistory} from 'admin/components/deleteBillingMetricHistory';
import type {ActionItem, BadgeItem} from 'admin/components/detailsPage';
import {DetailsPage} from 'admin/components/detailsPage';
-import ForkCustomerAction from 'admin/components/forkCustomer';
+import {ForkCustomerAction} from 'admin/components/forkCustomer';
import {triggerEndPeriodEarlyModal} from 'admin/components/nextBillingPeriodAction';
import {triggerProvisionSubscription} from 'admin/components/provisionSubscriptionAction';
import {refundVercelRequest} from 'admin/components/refundVercelRequestModal';
import {SelectableContainer} from 'admin/components/selectableContainer';
import SendWeeklyEmailAction from 'admin/components/sendWeeklyEmailAction';
-import SponsorshipAction from 'admin/components/sponsorshipAction';
-import SuspendAccountAction from 'admin/components/suspendAccountAction';
+import {SponsorshipAction} from 'admin/components/sponsorshipAction';
+import {SuspendAccountAction} from 'admin/components/suspendAccountAction';
import {openToggleConsolePlatformsModal} from 'admin/components/toggleConsolePlatformsModal';
import {toggleSpendAllocationModal} from 'admin/components/toggleSpendAllocationModal';
-import TrialSubscriptionAction from 'admin/components/trialSubscriptionAction';
+import {TrialSubscriptionAction} from 'admin/components/trialSubscriptionAction';
import {RESERVED_BUDGET_QUOTA} from 'getsentry/constants';
import type {BilledDataCategoryInfo, BillingConfig, Subscription} from 'getsentry/types';
import {
diff --git a/static/gsAdmin/views/dynamicSamplingPanel.tsx b/static/gsAdmin/views/dynamicSamplingPanel.tsx
index 51f5e85ddd31be..da6c41b6aa2562 100644
--- a/static/gsAdmin/views/dynamicSamplingPanel.tsx
+++ b/static/gsAdmin/views/dynamicSamplingPanel.tsx
@@ -13,7 +13,7 @@ import {Tooltip} from '@sentry/scraps/tooltip';
import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
import {DateTime} from 'sentry/components/dateTime';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {Panel} from 'sentry/components/panels/panel';
import {PanelBody} from 'sentry/components/panels/panelBody';
import {PanelHeader} from 'sentry/components/panels/panelHeader';
diff --git a/static/gsApp/components/profiling/profilingUpgradeModal.tsx b/static/gsApp/components/profiling/profilingUpgradeModal.tsx
index 4c086ad244079e..95ecffdc75cc87 100644
--- a/static/gsApp/components/profiling/profilingUpgradeModal.tsx
+++ b/static/gsApp/components/profiling/profilingUpgradeModal.tsx
@@ -10,7 +10,7 @@ import {ExternalLink} from '@sentry/scraps/link';
import {addSuccessMessage} from 'sentry/actionCreators/indicator';
import type {ModalRenderProps} from 'sentry/actionCreators/modal';
import {closeModal} from 'sentry/actionCreators/modal';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {HighlightModalContainer} from 'sentry/components/highlightModalContainer';
import {List} from 'sentry/components/list';
import {ListItem} from 'sentry/components/list/listItem';
diff --git a/static/gsApp/components/upgradeNowModal/index.tsx b/static/gsApp/components/upgradeNowModal/index.tsx
index cf6af59e2c6e8a..470f79a0cdebeb 100644
--- a/static/gsApp/components/upgradeNowModal/index.tsx
+++ b/static/gsApp/components/upgradeNowModal/index.tsx
@@ -4,7 +4,7 @@ import styled from '@emotion/styled';
import {ExternalLink} from '@sentry/scraps/link';
import type {ModalRenderProps} from 'sentry/actionCreators/modal';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {HighlightModalContainer} from 'sentry/components/highlightModalContainer';
import {List} from 'sentry/components/list';
import {ListItem} from 'sentry/components/list/listItem';
diff --git a/static/gsApp/components/upsellModal/details.spec.tsx b/static/gsApp/components/upsellModal/details.spec.tsx
index 18e3d934684089..43be1f963a404e 100644
--- a/static/gsApp/components/upsellModal/details.spec.tsx
+++ b/static/gsApp/components/upsellModal/details.spec.tsx
@@ -4,7 +4,7 @@ import {BillingConfigFixture} from 'getsentry-test/fixtures/billingConfig';
import {SubscriptionFixture} from 'getsentry-test/fixtures/subscription';
import {act, render, screen} from 'sentry-test/reactTestingLibrary';
-import Details from 'getsentry/components/upsellModal/details';
+import {Details} from 'getsentry/components/upsellModal/details';
import {PlanTier} from 'getsentry/types';
describe('Upsell Modal Details', () => {
diff --git a/static/gsApp/components/upsellModal/details.tsx b/static/gsApp/components/upsellModal/details.tsx
index 0c0e82391410d8..0c0c51ca55521c 100644
--- a/static/gsApp/components/upsellModal/details.tsx
+++ b/static/gsApp/components/upsellModal/details.tsx
@@ -208,7 +208,7 @@ const PERFORMANCE_FEATURES = selectFeatures([
'user-misery',
]).filter(Boolean);
-class Body extends Component {
+export class Details extends Component {
constructor(props: Props) {
super(props);
@@ -486,5 +486,3 @@ const featureContentAnimation = {
}),
},
};
-
-export default Body;
diff --git a/static/gsApp/components/upsellModal/index.tsx b/static/gsApp/components/upsellModal/index.tsx
index 88fef681a9d7f3..6777ea0ba77987 100644
--- a/static/gsApp/components/upsellModal/index.tsx
+++ b/static/gsApp/components/upsellModal/index.tsx
@@ -11,7 +11,7 @@ import {withSubscription} from 'getsentry/components/withSubscription';
import type {Subscription} from 'getsentry/types';
import {getTrialDaysLeft, getTrialLength, hasPerformance} from 'getsentry/utils/billing';
-import Details from './details';
+import {Details} from './details';
type Props = ModalRenderProps & {
organization: Organization;
diff --git a/static/gsApp/hooks/firstPartyIntegrationAlertHook.tsx b/static/gsApp/hooks/firstPartyIntegrationAlertHook.tsx
index 3e511bad22d924..41e320fa312eb6 100644
--- a/static/gsApp/hooks/firstPartyIntegrationAlertHook.tsx
+++ b/static/gsApp/hooks/firstPartyIntegrationAlertHook.tsx
@@ -5,7 +5,7 @@ import {Flex} from '@sentry/scraps/layout';
import {t} from 'sentry/locale';
import type {Integration} from 'sentry/types/integrations';
-import AlertContainer from 'sentry/views/settings/organizationIntegrations/integrationAlertContainer';
+import {AlertContainer} from 'sentry/views/settings/organizationIntegrations/integrationAlertContainer';
import {UpsellButton} from 'getsentry/components/upsellButton';
diff --git a/static/gsApp/hooks/integrationFeatures.spec.tsx b/static/gsApp/hooks/integrationFeatures.spec.tsx
index d5a5cb7dbadc23..340e4c3991640d 100644
--- a/static/gsApp/hooks/integrationFeatures.spec.tsx
+++ b/static/gsApp/hooks/integrationFeatures.spec.tsx
@@ -9,7 +9,7 @@ import {render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
import {ConfigStore} from 'sentry/stores/configStore';
-import hookIntegrationFeatures from 'getsentry/hooks/integrationFeatures';
+import {hookIntegrationFeatures} from 'getsentry/hooks/integrationFeatures';
import {SubscriptionStore} from 'getsentry/stores/subscriptionStore';
import {PlanTier} from 'getsentry/types';
diff --git a/static/gsApp/hooks/integrationFeatures.tsx b/static/gsApp/hooks/integrationFeatures.tsx
index 2086caac69ddde..1ba5ce1cabb5ce 100644
--- a/static/gsApp/hooks/integrationFeatures.tsx
+++ b/static/gsApp/hooks/integrationFeatures.tsx
@@ -332,9 +332,7 @@ const FeatureDescription = styled('li')`
* - FeatureList
* Renders a list of integration features grouped by plan.
*/
-const hookIntegrationFeatures = () => ({
+export const hookIntegrationFeatures: Hooks['integrations:feature-gates'] = () => ({
IntegrationFeatures,
FeatureList,
});
-
-export default hookIntegrationFeatures as Hooks['integrations:feature-gates'];
diff --git a/static/gsApp/hooks/spendVisibility/enhancedUsageStatsOrganization.tsx b/static/gsApp/hooks/spendVisibility/enhancedUsageStatsOrganization.tsx
index 9f9c2f3ae19daa..780d7b75e1b320 100644
--- a/static/gsApp/hooks/spendVisibility/enhancedUsageStatsOrganization.tsx
+++ b/static/gsApp/hooks/spendVisibility/enhancedUsageStatsOrganization.tsx
@@ -2,7 +2,7 @@ import {Fragment, useMemo} from 'react';
import styled from '@emotion/styled';
import {getSeriesApiInterval} from 'sentry/components/charts/utils';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {Pagination} from 'sentry/components/pagination';
import {DATA_CATEGORY_INFO} from 'sentry/constants';
import {tct} from 'sentry/locale';
diff --git a/static/gsApp/registerHooks.tsx b/static/gsApp/registerHooks.tsx
index 452445bca717f1..0dc7f12d49faac 100644
--- a/static/gsApp/registerHooks.tsx
+++ b/static/gsApp/registerHooks.tsx
@@ -55,7 +55,7 @@ import {FirstPartyIntegrationAlertHook} from 'getsentry/hooks/firstPartyIntegrat
import GithubInstallationSelectInstallButton from 'getsentry/hooks/githubInstallationSelectInstall';
import {handleGuideUpdate} from 'getsentry/hooks/handleGuideUpdate';
import {handleMonitorCreated} from 'getsentry/hooks/handleMonitorCreated';
-import hookIntegrationFeatures from 'getsentry/hooks/integrationFeatures';
+import {hookIntegrationFeatures} from 'getsentry/hooks/integrationFeatures';
import {legacyOrganizationRedirectRoutes} from 'getsentry/hooks/legacyOrganizationRedirectRoutes';
import MemberListHeader from 'getsentry/hooks/memberListHeader';
import {OrganizationMembershipSettingsForm} from 'getsentry/hooks/organizationMembershipSettingsForm';
diff --git a/static/gsApp/views/decideCheckout.tsx b/static/gsApp/views/decideCheckout.tsx
index e29c48314a1b13..97c9f75d6b5f3a 100644
--- a/static/gsApp/views/decideCheckout.tsx
+++ b/static/gsApp/views/decideCheckout.tsx
@@ -1,4 +1,4 @@
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import {useLocation} from 'sentry/utils/useLocation';
import {useNavigate} from 'sentry/utils/useNavigate';
import {useOrganization} from 'sentry/utils/useOrganization';
diff --git a/static/gsApp/views/seerAutomation/onboarding/onboardingLegacy.tsx b/static/gsApp/views/seerAutomation/onboarding/onboardingLegacy.tsx
index 4a654edf43ed73..2e528aa18bf0af 100644
--- a/static/gsApp/views/seerAutomation/onboarding/onboardingLegacy.tsx
+++ b/static/gsApp/views/seerAutomation/onboarding/onboardingLegacy.tsx
@@ -23,7 +23,7 @@ import {
GuidedSteps,
useGuidedStepsContext,
} from 'sentry/components/guidedSteps/guidedSteps';
-import ExternalLink from 'sentry/components/links/externalLink';
+import {ExternalLink} from 'sentry/components/links/externalLink';
import {LoadingIndicator} from 'sentry/components/loadingIndicator';
import {NoProjectMessage} from 'sentry/components/noProjectMessage';
import {Panel} from 'sentry/components/panels/panel';
diff --git a/static/gsApp/views/subscriptionPage/headerCards/headerCards.tsx b/static/gsApp/views/subscriptionPage/headerCards/headerCards.tsx
index ddc694e77343c9..b9570259d70145 100644
--- a/static/gsApp/views/subscriptionPage/headerCards/headerCards.tsx
+++ b/static/gsApp/views/subscriptionPage/headerCards/headerCards.tsx
@@ -1,6 +1,6 @@
import {Grid} from '@sentry/scraps/layout';
-import ErrorBoundary from 'sentry/components/errorBoundary';
+import {ErrorBoundary} from 'sentry/components/errorBoundary';
import type {Organization} from 'sentry/types/organization';
import {useSecondaryNavigation} from 'sentry/views/navigation/secondaryNavigationContext';
diff --git a/tests/js/sentry-test/performance/initializePerformanceData.ts b/tests/js/sentry-test/performance/initializePerformanceData.ts
index 69f1c291449806..55a57623fa75b3 100644
--- a/tests/js/sentry-test/performance/initializePerformanceData.ts
+++ b/tests/js/sentry-test/performance/initializePerformanceData.ts
@@ -4,7 +4,7 @@ import {ProjectFixture} from 'sentry-fixture/project';
import {initializeOrg} from 'sentry-test/initializeOrg';
import type {Project} from 'sentry/types/project';
-import EventView from 'sentry/utils/discover/eventView';
+import {EventView} from 'sentry/utils/discover/eventView';
export interface InitializeDataSettings {
features?: string[];
From de9846d789f6d7fb9962b385bf30bfb1279260e4 Mon Sep 17 00:00:00 2001
From: Lyn Nagara <1779792+lynnagara@users.noreply.github.com>
Date: Tue, 24 Mar 2026 10:59:21 -0700
Subject: [PATCH 15/38] ref(cells): Add cell_name support to rpc dataclasses
(#111169)
Same idea as https://github.com/getsentry/sentry/pull/111039 for the
rest of the rpc dataclasses
merge only after successful deploy on
https://github.com/getsentry/sentry/pull/111039 first
---
.../control_organization_provisioning/model.py | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/sentry/hybridcloud/services/control_organization_provisioning/model.py b/src/sentry/hybridcloud/services/control_organization_provisioning/model.py
index 20e76051f7c38b..e72dfd93ef27ce 100644
--- a/src/sentry/hybridcloud/services/control_organization_provisioning/model.py
+++ b/src/sentry/hybridcloud/services/control_organization_provisioning/model.py
@@ -1,3 +1,7 @@
+from typing import Any
+
+from pydantic import root_validator
+
from sentry.hybridcloud.rpc import RpcModel
@@ -8,3 +12,14 @@ class RpcOrganizationSlugReservation(RpcModel):
slug: str
region_name: str
reservation_type: int
+
+ @root_validator(pre=True)
+ @classmethod
+ def _accept_cell_name(cls, values: dict[str, Any]) -> dict[str, Any]:
+ if "cell_name" in values and "region_name" not in values:
+ values["region_name"] = values.pop("cell_name")
+ return values
+
+ @property
+ def cell_name(self) -> str:
+ return self.region_name
From 1b5d3e48f49a234db5a32e8fd7d7a5f762d85c69 Mon Sep 17 00:00:00 2001
From: Charlie Luo
Date: Tue, 24 Mar 2026 11:10:02 -0700
Subject: [PATCH 16/38] ref(tasks): move seer-related tasks to their own folder
(#111380)
Noticing that app-backend is getting tagged for changes in miscellaneous
seer tasks (e.g.
https://github.com/getsentry/sentry/pull/111375/changes). Split
seer-related tasks into a separate folder, similar to the other tasks in
`src/sentry/tasks`.
Co-authored-by: Claude
---
.github/CODEOWNERS | 7 +-
.github/codeowners-coverage-baseline.txt | 4 -
pyproject.toml | 4 +-
src/sentry/conf/server.py | 10 +-
src/sentry/core/endpoints/project_details.py | 2 +-
src/sentry/deletions/defaults/group.py | 4 +-
.../organization_repository_details.py | 2 +-
src/sentry/seer/autofix/autofix.py | 2 +-
src/sentry/seer/similarity/similar_issues.py | 2 +-
src/sentry/tasks/autofix.py | 306 +----------------
src/sentry/tasks/context_engine_index.py | 312 +-----------------
src/sentry/tasks/post_process.py | 2 +-
src/sentry/tasks/seer/__init__.py | 0
src/sentry/tasks/seer/autofix.py | 303 +++++++++++++++++
src/sentry/tasks/{seer.py => seer/cleanup.py} | 0
src/sentry/tasks/seer/context_engine_index.py | 299 +++++++++++++++++
.../delete_seer_grouping_records.py | 0
.../explorer_index.py} | 0
tests/sentry/api/helpers/test_group_index.py | 2 +-
.../core/endpoints/test_project_details.py | 2 +-
tests/sentry/deletions/test_group.py | 4 +-
.../test_organization_repository_details.py | 12 +-
tests/sentry/seer/autofix/test_autofix.py | 4 +-
.../seer/endpoints/test_group_ai_autofix.py | 10 +-
.../test_explorer_service_map_utils.py | 18 +-
tests/sentry/tasks/seer/__init__.py | 0
tests/sentry/tasks/{ => seer}/test_autofix.py | 56 ++--
.../{test_seer.py => seer/test_cleanup.py} | 8 +-
.../{ => seer}/test_context_engine_index.py | 42 +--
.../test_delete_seer_grouping_records.py | 14 +-
.../test_explorer_index.py} | 22 +-
tests/sentry/tasks/test_post_process.py | 36 +-
32 files changed, 756 insertions(+), 733 deletions(-)
create mode 100644 src/sentry/tasks/seer/__init__.py
create mode 100644 src/sentry/tasks/seer/autofix.py
rename src/sentry/tasks/{seer.py => seer/cleanup.py} (100%)
create mode 100644 src/sentry/tasks/seer/context_engine_index.py
rename src/sentry/tasks/{ => seer}/delete_seer_grouping_records.py (100%)
rename src/sentry/tasks/{seer_explorer_index.py => seer/explorer_index.py} (100%)
create mode 100644 tests/sentry/tasks/seer/__init__.py
rename tests/sentry/tasks/{ => seer}/test_autofix.py (87%)
rename tests/sentry/tasks/{test_seer.py => seer/test_cleanup.py} (89%)
rename tests/sentry/tasks/{ => seer}/test_context_engine_index.py (79%)
rename tests/sentry/tasks/{ => seer}/test_delete_seer_grouping_records.py (89%)
rename tests/sentry/tasks/{test_seer_explorer_index.py => seer/test_explorer_index.py} (95%)
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 2be68ee062021f..8234430565efde 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -598,6 +598,8 @@ tests/sentry/api/endpoints/test_organization_attribute_mappings.py @get
/tests/sentry/seer/ @getsentry/machine-learning-ai
/src/sentry/seer/fetch_issues/ @getsentry/machine-learning-ai @getsentry/coding-workflows-sentry-backend
/tests/sentry/seer/fetch_issues/ @getsentry/machine-learning-ai @getsentry/coding-workflows-sentry-backend
+/src/sentry/tasks/seer/ @getsentry/machine-learning-ai
+/tests/sentry/tasks/seer/ @getsentry/machine-learning-ai
## End of ML & AI
## Issues
@@ -648,7 +650,7 @@ tests/sentry/api/endpoints/test_organization_attribute_mappings.py @get
/src/sentry/tasks/clear_expired_snoozes.py @getsentry/issue-detection-backend
/src/sentry/tasks/codeowners/ @getsentry/issue-detection-backend
/src/sentry/tasks/commit_context.py @getsentry/issue-detection-backend
-/src/sentry/tasks/delete_seer_grouping_records.py @getsentry/issue-detection-backend
+/src/sentry/tasks/seer/delete_seer_grouping_records.py @getsentry/issue-detection-backend
/src/sentry/tasks/embeddings_grouping/ @getsentry/issue-detection-backend
/src/sentry/tasks/groupowner.py @getsentry/issue-detection-backend
/src/sentry/tasks/merge.py @getsentry/issue-detection-backend
@@ -686,14 +688,13 @@ tests/sentry/api/endpoints/test_organization_attribute_mappings.py @get
/tests/sentry/tasks/test_auto_ongoing_issues.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_auto_remove_inbox.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_auto_resolve_issues.py @getsentry/issue-detection-backend
-/tests/sentry/tasks/test_backfill_seer_grouping_records.py @getsentry/issue-detection-backend
+/tests/sentry/tasks/seer/test_delete_seer_grouping_records.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_check_new_issue_threshold_met.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_clear_expired_resolutions.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_clear_expired_rulesnoozes.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_clear_expired_snoozes.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_code_owners.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_commit_context.py @getsentry/issue-detection-backend
-/tests/sentry/tasks/test_delete_seer_grouping_records.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_groupowner.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_merge.py @getsentry/issue-detection-backend
/tests/sentry/tasks/test_post_process.py @getsentry/issue-detection-backend
diff --git a/.github/codeowners-coverage-baseline.txt b/.github/codeowners-coverage-baseline.txt
index ea41e79b23e446..d79b9005dda2c9 100644
--- a/.github/codeowners-coverage-baseline.txt
+++ b/.github/codeowners-coverage-baseline.txt
@@ -2523,14 +2523,12 @@ tests/sentry/tasks/test_activity.py
tests/sentry/tasks/test_assemble.py
tests/sentry/tasks/test_auth.py
tests/sentry/tasks/test_auto_enable_codecov.py
-tests/sentry/tasks/test_autofix.py
tests/sentry/tasks/test_base.py
tests/sentry/tasks/test_beacon.py
tests/sentry/tasks/test_check_am2_compatibility.py
tests/sentry/tasks/test_check_auth.py
tests/sentry/tasks/test_collect_project_platforms.py
tests/sentry/tasks/test_commits.py
-tests/sentry/tasks/test_context_engine_index.py
tests/sentry/tasks/test_delete_pending_groups.py
tests/sentry/tasks/test_digests.py
tests/sentry/tasks/test_email.py
@@ -2540,8 +2538,6 @@ tests/sentry/tasks/test_organization_contributors.py
tests/sentry/tasks/test_process_buffer.py
tests/sentry/tasks/test_relay.py
tests/sentry/tasks/test_reprocessing2.py
-tests/sentry/tasks/test_seer.py
-tests/sentry/tasks/test_seer_explorer_index.py
tests/sentry/tasks/test_store.py
tests/sentry/tasks/test_symbolication.py
tests/sentry/tasks/test_update_code_owners_schema.py
diff --git a/pyproject.toml b/pyproject.toml
index ce788d1ada3ce7..92c8d452851c2f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -676,9 +676,9 @@ module = [
"sentry.tasks.beacon",
"sentry.tasks.codeowners.*",
"sentry.tasks.commit_context",
- "sentry.tasks.delete_seer_grouping_records",
"sentry.tasks.on_demand_metrics",
"sentry.tasks.reprocessing2",
+ "sentry.tasks.seer.delete_seer_grouping_records",
"sentry.tasks.store",
"sentry.tasks.unmerge",
"sentry.taskworker.*",
@@ -888,8 +888,8 @@ module = [
"tests.sentry.snuba.test_tasks",
"tests.sentry.spans.grouping.*",
"tests.sentry.tasks.integrations.*",
+ "tests.sentry.tasks.seer.test_delete_seer_grouping_records",
"tests.sentry.tasks.test_code_owners",
- "tests.sentry.tasks.test_delete_seer_grouping_records",
"tests.sentry.tasks.test_on_demand_metrics",
"tests.sentry.tempest.*",
"tests.sentry.templatetags.*",
diff --git a/src/sentry/conf/server.py b/src/sentry/conf/server.py
index 3eff734b4e2f07..c1666aa3b34557 100644
--- a/src/sentry/conf/server.py
+++ b/src/sentry/conf/server.py
@@ -925,7 +925,7 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
"sentry.tasks.auto_remove_inbox",
"sentry.tasks.auto_resolve_issues",
"sentry.tasks.auto_source_code_config",
- "sentry.tasks.autofix",
+ "sentry.tasks.seer.autofix",
"sentry.tasks.beacon",
"sentry.tasks.check_am2_compatibility",
"sentry.tasks.clear_expired_resolutions",
@@ -937,7 +937,7 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
"sentry.tasks.commit_context",
"sentry.tasks.commits",
"sentry.tasks.delete_pending_groups",
- "sentry.tasks.delete_seer_grouping_records",
+ "sentry.tasks.seer.delete_seer_grouping_records",
"sentry.tasks.digests",
"sentry.tasks.email",
"sentry.tasks.files",
@@ -957,7 +957,7 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
"sentry.tasks.repository",
"sentry.tasks.reprocessing2",
"sentry.tasks.scim.privilege_sync",
- "sentry.tasks.seer",
+ "sentry.tasks.seer.cleanup",
"sentry.tasks.statistical_detectors",
"sentry.tasks.store",
"sentry.tasks.summaries.weekly_reports",
@@ -975,8 +975,8 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
"sentry.workflow_engine.tasks.delayed_workflows",
"sentry.workflow_engine.tasks.workflows",
"sentry.workflow_engine.tasks.actions",
- "sentry.tasks.seer_explorer_index",
- "sentry.tasks.context_engine_index",
+ "sentry.tasks.seer.explorer_index",
+ "sentry.tasks.seer.context_engine_index",
# Used for tests
"sentry.taskworker.tasks.examples",
)
diff --git a/src/sentry/core/endpoints/project_details.py b/src/sentry/core/endpoints/project_details.py
index eba14f7bb321e6..a4ecd79c357fcc 100644
--- a/src/sentry/core/endpoints/project_details.py
+++ b/src/sentry/core/endpoints/project_details.py
@@ -57,7 +57,7 @@
from sentry.notifications.utils import has_alert_integration
from sentry.relay.datascrubbing import validate_pii_config_update, validate_pii_selectors
from sentry.seer.autofix.constants import AutofixAutomationTuningSettings
-from sentry.tasks.delete_seer_grouping_records import call_seer_delete_project_grouping_records
+from sentry.tasks.seer.delete_seer_grouping_records import call_seer_delete_project_grouping_records
from sentry.tempest.utils import has_tempest_access
logger = logging.getLogger(__name__)
diff --git a/src/sentry/deletions/defaults/group.py b/src/sentry/deletions/defaults/group.py
index 197c6bc7cac6ef..aacaa44971e8a1 100644
--- a/src/sentry/deletions/defaults/group.py
+++ b/src/sentry/deletions/defaults/group.py
@@ -30,7 +30,9 @@
from sentry.notifications.models.notificationmessage import NotificationMessage
from sentry.services.eventstore.models import Event
from sentry.snuba.dataset import Dataset
-from sentry.tasks.delete_seer_grouping_records import may_schedule_task_to_delete_hashes_from_seer
+from sentry.tasks.seer.delete_seer_grouping_records import (
+ may_schedule_task_to_delete_hashes_from_seer,
+)
from sentry.utils import metrics
from ..base import BaseDeletionTask, BaseRelation, ModelDeletionTask, ModelRelation
diff --git a/src/sentry/integrations/api/endpoints/organization_repository_details.py b/src/sentry/integrations/api/endpoints/organization_repository_details.py
index a704c48878287f..c843b7c2ae7666 100644
--- a/src/sentry/integrations/api/endpoints/organization_repository_details.py
+++ b/src/sentry/integrations/api/endpoints/organization_repository_details.py
@@ -23,7 +23,7 @@
from sentry.models.organization import Organization
from sentry.models.repository import Repository
from sentry.tasks.repository import repository_cascade_delete_on_hide
-from sentry.tasks.seer import cleanup_seer_repository_preferences
+from sentry.tasks.seer.cleanup import cleanup_seer_repository_preferences
class RepositorySerializer(serializers.Serializer):
diff --git a/src/sentry/seer/autofix/autofix.py b/src/sentry/seer/autofix/autofix.py
index 087dd2cf7f03e1..302dedfad2d8ed 100644
--- a/src/sentry/seer/autofix/autofix.py
+++ b/src/sentry/seer/autofix/autofix.py
@@ -47,7 +47,7 @@
from sentry.services.eventstore.models import Event, GroupEvent
from sentry.snuba.ourlogs import OurLogs
from sentry.snuba.referrer import Referrer
-from sentry.tasks.autofix import check_autofix_status
+from sentry.tasks.seer.autofix import check_autofix_status
from sentry.users.models.user import User
from sentry.users.services.user.model import RpcUser
from sentry.utils.event_frames import EventFrame
diff --git a/src/sentry/seer/similarity/similar_issues.py b/src/sentry/seer/similarity/similar_issues.py
index eb1b9231d62ceb..0949679f28c4d6 100644
--- a/src/sentry/seer/similarity/similar_issues.py
+++ b/src/sentry/seer/similarity/similar_issues.py
@@ -23,7 +23,7 @@
SimilarHashNotFoundError,
SimilarIssuesEmbeddingsRequest,
)
-from sentry.tasks.delete_seer_grouping_records import delete_seer_grouping_records_by_hash
+from sentry.tasks.seer.delete_seer_grouping_records import delete_seer_grouping_records_by_hash
from sentry.utils import json, metrics
from sentry.utils.circuit_breaker2 import CircuitBreaker
from sentry.utils.json import JSONDecodeError
diff --git a/src/sentry/tasks/autofix.py b/src/sentry/tasks/autofix.py
index 86107ce8a348ea..fe0a41217d3ba5 100644
--- a/src/sentry/tasks/autofix.py
+++ b/src/sentry/tasks/autofix.py
@@ -1,303 +1,5 @@
-import logging
-from datetime import datetime, timedelta
+# Shim for backwards compatibility with getsentry imports.
+# Remove once getsentry is updated to import from sentry.tasks.seer.autofix.
+from sentry.tasks.seer.autofix import configure_seer_for_existing_org
-import sentry_sdk
-from django.utils import timezone
-from taskbroker_client.retry import Retry
-from taskbroker_client.state import current_task
-
-from sentry import analytics, features
-from sentry.analytics.events.autofix_automation_events import AiAutofixAutomationEvent
-from sentry.constants import ObjectStatus
-from sentry.models.group import Group
-from sentry.models.organization import Organization
-from sentry.models.project import Project
-from sentry.seer.autofix.constants import (
- AutofixAutomationTuningSettings,
- AutofixStatus,
- SeerAutomationSource,
-)
-from sentry.seer.autofix.utils import (
- bulk_get_project_preferences,
- bulk_set_project_preferences,
- bulk_write_preferences_to_sentry_db,
- deduplicate_repositories,
- get_autofix_repos_from_project_code_mappings,
- get_autofix_state,
- get_seer_seat_based_tier_cache_key,
- resolve_repository_ids,
-)
-from sentry.seer.models import SeerProjectPreference
-from sentry.tasks.base import instrumented_task
-from sentry.taskworker.namespaces import ingest_errors_tasks, issues_tasks
-from sentry.utils import metrics
-from sentry.utils.cache import cache
-
-logger = logging.getLogger(__name__)
-
-
-def _get_group_or_log(group_id: int, task_name: str) -> Group | None:
- """Fetch a Group by ID, returning None and logging a warning if it no longer exists."""
- try:
- return Group.objects.get(id=group_id)
- except Group.DoesNotExist:
- logger.warning("%s.group_not_found", task_name, extra={"group_id": group_id})
- return None
-
-
-@instrumented_task(
- name="sentry.tasks.autofix.check_autofix_status",
- namespace=issues_tasks,
- retry=Retry(times=1),
-)
-def check_autofix_status(run_id: int, organization_id: int) -> None:
- state = get_autofix_state(run_id=run_id, organization_id=organization_id)
-
- if (
- state
- and state.status == AutofixStatus.PROCESSING
- and state.updated_at < datetime.now() - timedelta(minutes=5)
- ):
- # This should log to sentry
- logger.error(
- "Autofix run has been processing for more than 5 minutes", extra={"run_id": run_id}
- )
-
-
-@instrumented_task(
- name="sentry.tasks.autofix.generate_summary_and_run_automation",
- namespace=ingest_errors_tasks,
- processing_deadline_duration=35,
- retry=Retry(times=1),
-)
-def generate_summary_and_run_automation(group_id: int, **kwargs) -> None:
- from sentry.seer.autofix.issue_summary import get_issue_summary
-
- trigger_path = kwargs.get("trigger_path", "unknown")
- sentry_sdk.set_tag("trigger_path", trigger_path)
-
- group = _get_group_or_log(group_id, "generate_summary_and_run_automation")
- if group is None:
- return
- organization = group.project.organization
-
- task_state = current_task()
- if task_state is None or task_state.attempt == 0:
- metrics.incr("sentry.tasks.autofix.generate_summary_and_run_automation", sample_rate=1.0)
- analytics.record(
- AiAutofixAutomationEvent(
- organization_id=organization.id,
- project_id=group.project_id,
- group_id=group.id,
- task_name="generate_summary_and_run_automation",
- issue_event_count=group.times_seen,
- fixability_score=group.seer_fixability_score,
- )
- )
-
- get_issue_summary(group=group, source=SeerAutomationSource.POST_PROCESS)
-
-
-@instrumented_task(
- name="sentry.tasks.autofix.generate_issue_summary_only",
- namespace=ingest_errors_tasks,
- processing_deadline_duration=35,
- retry=Retry(times=3, delay=3, on=(Exception,)),
-)
-def generate_issue_summary_only(group_id: int) -> None:
- """
- Generate issue summary WITHOUT triggering automation.
- Used for triage signals flow when event count < 10 or when summary doesn't exist yet.
- """
- from sentry.seer.autofix.issue_summary import (
- get_and_update_group_fixability_score,
- get_issue_summary,
- )
-
- group = _get_group_or_log(group_id, "generate_issue_summary_only")
- if group is None:
- return
- organization = group.project.organization
-
- task_state = current_task()
- if task_state is None or task_state.attempt == 0:
- metrics.incr("sentry.tasks.autofix.generate_issue_summary_only", sample_rate=1.0)
- analytics.record(
- AiAutofixAutomationEvent(
- organization_id=organization.id,
- project_id=group.project_id,
- group_id=group.id,
- task_name="generate_issue_summary_only",
- issue_event_count=group.times_seen,
- fixability_score=group.seer_fixability_score,
- )
- )
-
- # Generate and cache the summary
- get_issue_summary(
- group=group, source=SeerAutomationSource.POST_PROCESS, should_run_automation=False
- )
-
- get_and_update_group_fixability_score(group, force_generate=True)
-
-
-@instrumented_task(
- name="sentry.tasks.autofix.run_automation_only_task",
- namespace=ingest_errors_tasks,
- processing_deadline_duration=35,
- retry=Retry(times=1),
-)
-def run_automation_only_task(group_id: int) -> None:
- """
- Run automation directly for a group (assumes summary and fixability already exist).
- Used for triage signals flow when event count >= 10 and summary exists.
- """
- from django.contrib.auth.models import AnonymousUser
-
- from sentry.seer.autofix.issue_summary import run_automation
-
- group = _get_group_or_log(group_id, "run_automation_only_task")
- if group is None:
- return
- organization = group.project.organization
-
- task_state = current_task()
- if task_state is None or task_state.attempt == 0:
- metrics.incr("sentry.tasks.autofix.run_automation_only_task", sample_rate=1.0)
- analytics.record(
- AiAutofixAutomationEvent(
- organization_id=organization.id,
- project_id=group.project_id,
- group_id=group.id,
- task_name="run_automation_only",
- issue_event_count=group.times_seen,
- fixability_score=group.seer_fixability_score,
- )
- )
-
- event = group.get_latest_event()
-
- if not event:
- logger.warning("run_automation_only_task.no_event_found", extra={"group_id": group_id})
- return
-
- # Track issue age when running automation
- issue_age_days = int((timezone.now() - group.first_seen).total_seconds() / (60 * 60 * 24))
- metrics.distribution(
- "seer.automation.issue_age_since_first_seen", issue_age_days, unit="day", sample_rate=1.0
- )
-
- run_automation(
- group=group, user=AnonymousUser(), event=event, source=SeerAutomationSource.POST_PROCESS
- )
-
-
-@instrumented_task(
- name="sentry.tasks.autofix.configure_seer_for_existing_org",
- namespace=issues_tasks,
- processing_deadline_duration=90,
- retry=Retry(times=3),
-)
-def configure_seer_for_existing_org(organization_id: int) -> None:
- """
- Configure Seer settings for a new or existing organization migrating to new Seer pricing.
-
- Sets:
- - Project-level (all projects): seer_scanner_automation=True, autofix_automation_tuning="medium" or "off"
- - Seer API (all projects): automated_run_stopping_point="code_changes" or "open_pr"
-
- Ignores:
- - Org-level: enable_seer_coding
- """
-
- organization = Organization.objects.get(id=organization_id)
-
- sentry_sdk.set_tag("organization_id", organization.id)
- sentry_sdk.set_tag("organization_slug", organization.slug)
-
- # Set org-level options
- organization.update_option(
- "sentry:default_autofix_automation_tuning", AutofixAutomationTuningSettings.MEDIUM
- )
-
- projects = list(
- Project.objects.filter(organization_id=organization_id, status=ObjectStatus.ACTIVE)
- )
- project_ids = [p.id for p in projects]
-
- if len(project_ids) == 0:
- return
-
- # If seer is enabled for an org, every project must have project level settings
- for project in projects:
- project.update_option("sentry:seer_scanner_automation", True)
- autofix_automation_tuning = project.get_option("sentry:autofix_automation_tuning")
- if autofix_automation_tuning != AutofixAutomationTuningSettings.OFF:
- project.update_option(
- "sentry:autofix_automation_tuning", AutofixAutomationTuningSettings.MEDIUM
- )
-
- preferences_by_id = bulk_get_project_preferences(organization_id, project_ids)
-
- # Determine which projects need updates
- preferences_to_set = []
- projects_by_id = {p.id: p for p in projects}
- for project_id in project_ids:
- existing_pref = preferences_by_id.get(str(project_id))
- if not existing_pref:
- # No existing preferences, get repositories from code mappings
- repositories = get_autofix_repos_from_project_code_mappings(projects_by_id[project_id])
- else:
- # Skip projects that already have an acceptable stopping point configured
- if existing_pref.get("automated_run_stopping_point") in ("open_pr", "code_changes"):
- continue
- repositories = existing_pref.get("repositories") or []
-
- repositories = deduplicate_repositories(repositories)
-
- # Preserve existing repositories and automation_handoff, only update the stopping point
- preferences_to_set.append(
- {
- "organization_id": organization_id,
- "project_id": project_id,
- "repositories": repositories or [],
- "automated_run_stopping_point": "code_changes",
- "automation_handoff": (
- existing_pref.get("automation_handoff") if existing_pref else None
- ),
- }
- )
-
- if len(preferences_to_set) > 0:
- bulk_set_project_preferences(organization_id, preferences_to_set)
-
- if features.has("organizations:seer-project-settings-dual-write", organization):
- try:
- validated_preferences = [
- SeerProjectPreference.validate(pref) for pref in preferences_to_set
- ]
- # Seer API responses don't include repository_id.
- # Resolve before dual-writing so repos aren't skipped.
- # This will not be necessary once we start keying by repo ID.
- resolved_preferences = resolve_repository_ids(
- organization_id, validated_preferences
- )
- bulk_write_preferences_to_sentry_db(projects, resolved_preferences)
- except Exception:
- logger.exception(
- "seer.write_preferences.failed", extra={"organization_id": organization_id}
- )
-
- # Invalidate existing cache entry and set cache to True to prevent race conditions where another
- # request re-caches False before the billing flag has fully propagated
- cache.set(get_seer_seat_based_tier_cache_key(organization_id), True, timeout=60 * 5)
-
- logger.info(
- "Task: configure_seer_for_existing_org completed",
- extra={
- "org_id": organization.id,
- "org_slug": organization.slug,
- "projects_configured": len(project_ids),
- "preferences_set_via_api": len(preferences_to_set),
- },
- )
+__all__ = ["configure_seer_for_existing_org"]
diff --git a/src/sentry/tasks/context_engine_index.py b/src/sentry/tasks/context_engine_index.py
index ce4a3386e89ff6..8d02a6a158d90c 100644
--- a/src/sentry/tasks/context_engine_index.py
+++ b/src/sentry/tasks/context_engine_index.py
@@ -1,299 +1,17 @@
-from __future__ import annotations
-
-import logging
-from datetime import UTC, datetime, timedelta, timezone
-
-import sentry_sdk
-from taskbroker_client.retry import Retry
-
-from sentry import features, options
-from sentry.constants import ObjectStatus
-from sentry.models.organization import Organization
-from sentry.models.project import Project
-from sentry.search.events.types import SnubaParams
-from sentry.seer.explorer.context_engine_utils import (
- EVENT_COUNT_LOOKBACK_DAYS,
- ProjectEventCounts,
- get_event_counts_for_org_projects,
- get_instrumentation_types,
- get_sdk_names_for_org_projects,
- get_top_span_ops_for_org_projects,
- get_top_transactions_for_org_projects,
-)
-from sentry.seer.explorer.explorer_service_map_utils import (
- _build_nodes,
- _query_service_dependencies,
- _send_to_seer,
-)
-from sentry.seer.models import SeerApiError
-from sentry.seer.signed_seer_api import (
- ExplorerIndexSentryKnowledgeRequest,
- OrgProjectKnowledgeIndexRequest,
- OrgProjectKnowledgeProjectData,
- SeerViewerContext,
- make_index_sentry_knowledge_request,
- make_org_project_knowledge_index_request,
-)
-from sentry.tasks.base import instrumented_task
-from sentry.taskworker.namespaces import seer_tasks
-from sentry.utils.hashlib import md5_text
-from sentry.utils.query import RangeQuerySetWrapper
-from sentry.utils.snuba_rpc import SnubaRPCRateLimitExceeded
-
-logger = logging.getLogger(__name__)
-
-
-@instrumented_task(
- name="sentry.tasks.context_engine_index.index_org_project_knowledge",
- namespace=seer_tasks,
- processing_deadline_duration=10 * 60,
-)
-def index_org_project_knowledge(org_id: int) -> None:
- """
- For a given org, list active projects, assemble project metadata and call
- the Seer endpoint to generate LLM summaries and embeddings.
- """
- if not options.get("explorer.context_engine_indexing.enable"):
- logger.info("explorer.context_engine_indexing.enable flag is disabled")
- return
-
- projects = list(
- Project.objects.filter(organization_id=org_id, status=ObjectStatus.ACTIVE).select_related(
- "organization"
- )
- )
- if not projects:
- logger.warning(
- "No projects found for index_org_project_knowledge",
- extra={"org_id": org_id},
- )
- return
-
- end = datetime.now(UTC)
- start = end - timedelta(days=EVENT_COUNT_LOOKBACK_DAYS)
-
- project_ids = [p.id for p in projects]
- event_counts = get_event_counts_for_org_projects(org_id, project_ids, start, end)
- high_volume_projects = [p for p in projects if p.id in event_counts]
- if not high_volume_projects:
- logger.info(
- "No high-volume projects found for index_org_project_knowledge",
- extra={"org_id": org_id, "num_projects": len(projects)},
- )
- return
-
- with sentry_sdk.start_span(op="explorer.context_engine.get_top_transactions_for_org_projects"):
- transactions_by_project = get_top_transactions_for_org_projects(
- high_volume_projects, start, end
- )
- with sentry_sdk.start_span(op="explorer.context_engine.get_top_span_ops_for_org_projects"):
- span_ops_by_project = get_top_span_ops_for_org_projects(high_volume_projects, start, end)
- with sentry_sdk.start_span(op="explorer.context_engine.get_sdk_names_for_org_projects"):
- sdk_names_by_project = get_sdk_names_for_org_projects(high_volume_projects, start, end)
-
- project_data: list[OrgProjectKnowledgeProjectData] = []
- for project in high_volume_projects:
- counts = event_counts.get(project.id, ProjectEventCounts())
- project_data.append(
- OrgProjectKnowledgeProjectData(
- project_id=project.id,
- slug=project.slug,
- sdk_name=sdk_names_by_project.get(project.id, ""),
- error_count=counts.error_count,
- transaction_count=counts.transaction_count,
- instrumentation=get_instrumentation_types(project),
- top_transactions=transactions_by_project.get(project.id, []),
- top_span_operations=span_ops_by_project.get(project.id, []),
- )
- )
-
- payload = OrgProjectKnowledgeIndexRequest(org_id=org_id, projects=project_data)
-
- viewer_context = SeerViewerContext(organization_id=org_id)
-
- try:
- response = make_org_project_knowledge_index_request(
- payload,
- timeout=30,
- viewer_context=viewer_context,
- )
- if response.status >= 400:
- raise SeerApiError("Seer request failed", response.status)
- except Exception:
- logger.exception(
- "Failed to call Seer org-project-knowledge endpoint",
- extra={"org_id": org_id, "num_projects": len(project_data)},
- )
- raise
-
- logger.info(
- "Successfully called Seer org-project-knowledge endpoint",
- extra={"org_id": org_id, "num_projects": len(project_data)},
- )
-
-
-@instrumented_task(
- name="sentry.tasks.context_engine_index.build_service_map",
- namespace=seer_tasks,
- processing_deadline_duration=10 * 60, # 10 minutes
- retry=Retry(times=3, on=(SnubaRPCRateLimitExceeded,), delay=60),
-)
-def build_service_map(organization_id: int, *args, **kwargs) -> None:
- """
- Build service map for a single organization and send to Seer.
-
- This task:
- 1. Checks feature flags
- 2. Queries Snuba for service dependencies
- 3. Classifies service roles using graph analysis
- 4. Sends data to Seer
-
- Args:
- organization_id: Organization ID to build map for
- """
- if not options.get("explorer.context_engine_indexing.enable"):
- logger.info("explorer.context_engine_indexing.enable flag is disabled")
- return
-
- logger.info(
- "Starting service map build",
- extra={"org_id": organization_id},
- )
-
- try:
- organization = Organization.objects.get(id=organization_id)
- projects = list(
- Project.objects.filter(organization_id=organization_id, status=ObjectStatus.ACTIVE)
- )
-
- if not projects:
- logger.info("No projects found for organization", extra={"org_id": organization_id})
- return
-
- end = datetime.now(timezone.utc)
- start = end - timedelta(hours=24)
-
- snuba_params = SnubaParams(
- start=start,
- end=end,
- projects=projects,
- organization=organization,
- )
-
- edges = _query_service_dependencies(snuba_params)
- nodes = _build_nodes(edges, projects)
-
- if not nodes:
- logger.info("No service map data found", extra={"org_id": organization_id})
- return
-
- _send_to_seer(organization_id, nodes, edges)
-
- logger.info(
- "Successfully completed service map build",
- extra={
- "org_id": organization_id,
- "edge_count": len(edges),
- "node_count": len(nodes),
- },
- )
-
- except Organization.DoesNotExist:
- logger.error("Organization not found", extra={"org_id": organization_id})
- return
- except Exception:
- sentry_sdk.capture_exception()
- logger.exception(
- "Failed to build service map",
- extra={"org_id": organization_id},
- )
- raise
-
-
-def get_allowed_org_ids_context_engine_indexing() -> list[int]:
- """
- Get the list of allowed organizations for context engine indexing.
-
- Divides all active orgs into 24 buckets via md5 hash of org ID. Only the bucket matching the current
- hour is checked for the seer-explorer-context-engine feature flag, keeping feature check
- volume at ~1/24th of total orgs.
- """
- with sentry_sdk.start_span(
- op="explorer.context_engine.get_allowed_org_ids_context_engine_indexing"
- ):
- now = datetime.now(UTC)
- TOTAL_HOURLY_SLOTS = 24
-
- eligible_org_ids: list[int] = []
-
- for org in RangeQuerySetWrapper(
- Organization.objects.filter(status=ObjectStatus.ACTIVE),
- result_value_getter=lambda o: o.id,
- ):
- # Ordering of these if blocks is very crucial. We want to check the hour first as
- # checking the feature flag is an expensive operation and we want to avoid it if possible.
- if int(md5_text(str(org.id)).hexdigest(), 16) % TOTAL_HOURLY_SLOTS == now.hour:
- with sentry_sdk.start_span(op="explorer.context_engine.has_feature"):
- if features.has("organizations:seer-explorer-context-engine", org):
- eligible_org_ids.append(org.id)
-
- return eligible_org_ids
-
-
-@instrumented_task(
- name="sentry.tasks.context_engine_index.schedule_context_engine_indexing_tasks",
- namespace=seer_tasks,
- processing_deadline_duration=30 * 60,
-)
-def schedule_context_engine_indexing_tasks() -> None:
- """
- Schedule context engine indexing tasks for all allowed organizations.
-
- Dispatches index_org_project_knowledge and build_service_map for each org
- with the seer-explorer-context-engine feature flag enabled.
- """
- if not options.get("explorer.context_engine_indexing.enable"):
- logger.info("explorer.context_engine_indexing.enable flag is disabled")
- return
-
- allowed_org_ids = get_allowed_org_ids_context_engine_indexing()
-
- dispatched = 0
- for org_id in allowed_org_ids:
- try:
- index_org_project_knowledge.apply_async(args=[org_id])
- build_service_map.apply_async(args=[org_id])
- dispatched += 1
- except Exception:
- logger.exception(
- "Failed to dispatch context engine tasks for org",
- extra={"org_id": org_id},
- )
-
- logger.info(
- "Scheduled context engine indexing tasks",
- extra={
- "orgs": allowed_org_ids[:10],
- "total_org_count": len(allowed_org_ids),
- "dispatched": dispatched,
- },
- )
-
-
-@instrumented_task(
- name="sentry.tasks.context_engine_index.index_sentry_knowledge",
- namespace=seer_tasks,
- processing_deadline_duration=30,
+# Shim for backwards compatibility with getsentry imports.
+# Remove once getsentry is updated to import from sentry.tasks.seer.context_engine_index.
+from sentry.tasks.seer.context_engine_index import (
+ build_service_map,
+ get_allowed_org_ids_context_engine_indexing,
+ index_org_project_knowledge,
+ index_sentry_knowledge,
+ schedule_context_engine_indexing_tasks,
)
-def index_sentry_knowledge() -> None:
- response = make_index_sentry_knowledge_request(
- body=ExplorerIndexSentryKnowledgeRequest(replace_existing=True)
- )
-
- if response.status >= 400:
- raise Exception(
- f"Seer sentry-knowledge endpoint returned {response.status}: {response.data.decode()}"
- )
- logger.info("Successfully called Seer sentry-knowledge endpoint")
- return None
+__all__ = [
+ "build_service_map",
+ "get_allowed_org_ids_context_engine_indexing",
+ "index_org_project_knowledge",
+ "index_sentry_knowledge",
+ "schedule_context_engine_indexing_tasks",
+]
diff --git a/src/sentry/tasks/post_process.py b/src/sentry/tasks/post_process.py
index aece13cb91cff9..54656f5aaeb061 100644
--- a/src/sentry/tasks/post_process.py
+++ b/src/sentry/tasks/post_process.py
@@ -1529,7 +1529,7 @@ def kick_off_seer_automation(job: PostProcessJob) -> None:
is_seer_scanner_rate_limited,
is_seer_seat_based_tier_enabled,
)
- from sentry.tasks.autofix import (
+ from sentry.tasks.seer.autofix import (
generate_issue_summary_only,
generate_summary_and_run_automation,
run_automation_only_task,
diff --git a/src/sentry/tasks/seer/__init__.py b/src/sentry/tasks/seer/__init__.py
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/src/sentry/tasks/seer/autofix.py b/src/sentry/tasks/seer/autofix.py
new file mode 100644
index 00000000000000..86107ce8a348ea
--- /dev/null
+++ b/src/sentry/tasks/seer/autofix.py
@@ -0,0 +1,303 @@
+import logging
+from datetime import datetime, timedelta
+
+import sentry_sdk
+from django.utils import timezone
+from taskbroker_client.retry import Retry
+from taskbroker_client.state import current_task
+
+from sentry import analytics, features
+from sentry.analytics.events.autofix_automation_events import AiAutofixAutomationEvent
+from sentry.constants import ObjectStatus
+from sentry.models.group import Group
+from sentry.models.organization import Organization
+from sentry.models.project import Project
+from sentry.seer.autofix.constants import (
+ AutofixAutomationTuningSettings,
+ AutofixStatus,
+ SeerAutomationSource,
+)
+from sentry.seer.autofix.utils import (
+ bulk_get_project_preferences,
+ bulk_set_project_preferences,
+ bulk_write_preferences_to_sentry_db,
+ deduplicate_repositories,
+ get_autofix_repos_from_project_code_mappings,
+ get_autofix_state,
+ get_seer_seat_based_tier_cache_key,
+ resolve_repository_ids,
+)
+from sentry.seer.models import SeerProjectPreference
+from sentry.tasks.base import instrumented_task
+from sentry.taskworker.namespaces import ingest_errors_tasks, issues_tasks
+from sentry.utils import metrics
+from sentry.utils.cache import cache
+
+logger = logging.getLogger(__name__)
+
+
+def _get_group_or_log(group_id: int, task_name: str) -> Group | None:
+ """Fetch a Group by ID, returning None and logging a warning if it no longer exists."""
+ try:
+ return Group.objects.get(id=group_id)
+ except Group.DoesNotExist:
+ logger.warning("%s.group_not_found", task_name, extra={"group_id": group_id})
+ return None
+
+
+@instrumented_task(
+ name="sentry.tasks.autofix.check_autofix_status",
+ namespace=issues_tasks,
+ retry=Retry(times=1),
+)
+def check_autofix_status(run_id: int, organization_id: int) -> None:
+ state = get_autofix_state(run_id=run_id, organization_id=organization_id)
+
+ if (
+ state
+ and state.status == AutofixStatus.PROCESSING
+ and state.updated_at < datetime.now() - timedelta(minutes=5)
+ ):
+ # This should log to sentry
+ logger.error(
+ "Autofix run has been processing for more than 5 minutes", extra={"run_id": run_id}
+ )
+
+
+@instrumented_task(
+ name="sentry.tasks.autofix.generate_summary_and_run_automation",
+ namespace=ingest_errors_tasks,
+ processing_deadline_duration=35,
+ retry=Retry(times=1),
+)
+def generate_summary_and_run_automation(group_id: int, **kwargs) -> None:
+ from sentry.seer.autofix.issue_summary import get_issue_summary
+
+ trigger_path = kwargs.get("trigger_path", "unknown")
+ sentry_sdk.set_tag("trigger_path", trigger_path)
+
+ group = _get_group_or_log(group_id, "generate_summary_and_run_automation")
+ if group is None:
+ return
+ organization = group.project.organization
+
+ task_state = current_task()
+ if task_state is None or task_state.attempt == 0:
+ metrics.incr("sentry.tasks.autofix.generate_summary_and_run_automation", sample_rate=1.0)
+ analytics.record(
+ AiAutofixAutomationEvent(
+ organization_id=organization.id,
+ project_id=group.project_id,
+ group_id=group.id,
+ task_name="generate_summary_and_run_automation",
+ issue_event_count=group.times_seen,
+ fixability_score=group.seer_fixability_score,
+ )
+ )
+
+ get_issue_summary(group=group, source=SeerAutomationSource.POST_PROCESS)
+
+
+@instrumented_task(
+ name="sentry.tasks.autofix.generate_issue_summary_only",
+ namespace=ingest_errors_tasks,
+ processing_deadline_duration=35,
+ retry=Retry(times=3, delay=3, on=(Exception,)),
+)
+def generate_issue_summary_only(group_id: int) -> None:
+ """
+ Generate issue summary WITHOUT triggering automation.
+ Used for triage signals flow when event count < 10 or when summary doesn't exist yet.
+ """
+ from sentry.seer.autofix.issue_summary import (
+ get_and_update_group_fixability_score,
+ get_issue_summary,
+ )
+
+ group = _get_group_or_log(group_id, "generate_issue_summary_only")
+ if group is None:
+ return
+ organization = group.project.organization
+
+ task_state = current_task()
+ if task_state is None or task_state.attempt == 0:
+ metrics.incr("sentry.tasks.autofix.generate_issue_summary_only", sample_rate=1.0)
+ analytics.record(
+ AiAutofixAutomationEvent(
+ organization_id=organization.id,
+ project_id=group.project_id,
+ group_id=group.id,
+ task_name="generate_issue_summary_only",
+ issue_event_count=group.times_seen,
+ fixability_score=group.seer_fixability_score,
+ )
+ )
+
+ # Generate and cache the summary
+ get_issue_summary(
+ group=group, source=SeerAutomationSource.POST_PROCESS, should_run_automation=False
+ )
+
+ get_and_update_group_fixability_score(group, force_generate=True)
+
+
+@instrumented_task(
+ name="sentry.tasks.autofix.run_automation_only_task",
+ namespace=ingest_errors_tasks,
+ processing_deadline_duration=35,
+ retry=Retry(times=1),
+)
+def run_automation_only_task(group_id: int) -> None:
+ """
+ Run automation directly for a group (assumes summary and fixability already exist).
+ Used for triage signals flow when event count >= 10 and summary exists.
+ """
+ from django.contrib.auth.models import AnonymousUser
+
+ from sentry.seer.autofix.issue_summary import run_automation
+
+ group = _get_group_or_log(group_id, "run_automation_only_task")
+ if group is None:
+ return
+ organization = group.project.organization
+
+ task_state = current_task()
+ if task_state is None or task_state.attempt == 0:
+ metrics.incr("sentry.tasks.autofix.run_automation_only_task", sample_rate=1.0)
+ analytics.record(
+ AiAutofixAutomationEvent(
+ organization_id=organization.id,
+ project_id=group.project_id,
+ group_id=group.id,
+ task_name="run_automation_only",
+ issue_event_count=group.times_seen,
+ fixability_score=group.seer_fixability_score,
+ )
+ )
+
+ event = group.get_latest_event()
+
+ if not event:
+ logger.warning("run_automation_only_task.no_event_found", extra={"group_id": group_id})
+ return
+
+ # Track issue age when running automation
+ issue_age_days = int((timezone.now() - group.first_seen).total_seconds() / (60 * 60 * 24))
+ metrics.distribution(
+ "seer.automation.issue_age_since_first_seen", issue_age_days, unit="day", sample_rate=1.0
+ )
+
+ run_automation(
+ group=group, user=AnonymousUser(), event=event, source=SeerAutomationSource.POST_PROCESS
+ )
+
+
+@instrumented_task(
+ name="sentry.tasks.autofix.configure_seer_for_existing_org",
+ namespace=issues_tasks,
+ processing_deadline_duration=90,
+ retry=Retry(times=3),
+)
+def configure_seer_for_existing_org(organization_id: int) -> None:
+ """
+ Configure Seer settings for a new or existing organization migrating to new Seer pricing.
+
+ Sets:
+ - Project-level (all projects): seer_scanner_automation=True, autofix_automation_tuning="medium" or "off"
+ - Seer API (all projects): automated_run_stopping_point="code_changes" or "open_pr"
+
+ Ignores:
+ - Org-level: enable_seer_coding
+ """
+
+ organization = Organization.objects.get(id=organization_id)
+
+ sentry_sdk.set_tag("organization_id", organization.id)
+ sentry_sdk.set_tag("organization_slug", organization.slug)
+
+ # Set org-level options
+ organization.update_option(
+ "sentry:default_autofix_automation_tuning", AutofixAutomationTuningSettings.MEDIUM
+ )
+
+ projects = list(
+ Project.objects.filter(organization_id=organization_id, status=ObjectStatus.ACTIVE)
+ )
+ project_ids = [p.id for p in projects]
+
+ if len(project_ids) == 0:
+ return
+
+ # If seer is enabled for an org, every project must have project level settings
+ for project in projects:
+ project.update_option("sentry:seer_scanner_automation", True)
+ autofix_automation_tuning = project.get_option("sentry:autofix_automation_tuning")
+ if autofix_automation_tuning != AutofixAutomationTuningSettings.OFF:
+ project.update_option(
+ "sentry:autofix_automation_tuning", AutofixAutomationTuningSettings.MEDIUM
+ )
+
+ preferences_by_id = bulk_get_project_preferences(organization_id, project_ids)
+
+ # Determine which projects need updates
+ preferences_to_set = []
+ projects_by_id = {p.id: p for p in projects}
+ for project_id in project_ids:
+ existing_pref = preferences_by_id.get(str(project_id))
+ if not existing_pref:
+ # No existing preferences, get repositories from code mappings
+ repositories = get_autofix_repos_from_project_code_mappings(projects_by_id[project_id])
+ else:
+ # Skip projects that already have an acceptable stopping point configured
+ if existing_pref.get("automated_run_stopping_point") in ("open_pr", "code_changes"):
+ continue
+ repositories = existing_pref.get("repositories") or []
+
+ repositories = deduplicate_repositories(repositories)
+
+ # Preserve existing repositories and automation_handoff, only update the stopping point
+ preferences_to_set.append(
+ {
+ "organization_id": organization_id,
+ "project_id": project_id,
+ "repositories": repositories or [],
+ "automated_run_stopping_point": "code_changes",
+ "automation_handoff": (
+ existing_pref.get("automation_handoff") if existing_pref else None
+ ),
+ }
+ )
+
+ if len(preferences_to_set) > 0:
+ bulk_set_project_preferences(organization_id, preferences_to_set)
+
+ if features.has("organizations:seer-project-settings-dual-write", organization):
+ try:
+ validated_preferences = [
+ SeerProjectPreference.validate(pref) for pref in preferences_to_set
+ ]
+ # Seer API responses don't include repository_id.
+ # Resolve before dual-writing so repos aren't skipped.
+ # This will not be necessary once we start keying by repo ID.
+ resolved_preferences = resolve_repository_ids(
+ organization_id, validated_preferences
+ )
+ bulk_write_preferences_to_sentry_db(projects, resolved_preferences)
+ except Exception:
+ logger.exception(
+ "seer.write_preferences.failed", extra={"organization_id": organization_id}
+ )
+
+ # Invalidate existing cache entry and set cache to True to prevent race conditions where another
+ # request re-caches False before the billing flag has fully propagated
+ cache.set(get_seer_seat_based_tier_cache_key(organization_id), True, timeout=60 * 5)
+
+ logger.info(
+ "Task: configure_seer_for_existing_org completed",
+ extra={
+ "org_id": organization.id,
+ "org_slug": organization.slug,
+ "projects_configured": len(project_ids),
+ "preferences_set_via_api": len(preferences_to_set),
+ },
+ )
diff --git a/src/sentry/tasks/seer.py b/src/sentry/tasks/seer/cleanup.py
similarity index 100%
rename from src/sentry/tasks/seer.py
rename to src/sentry/tasks/seer/cleanup.py
diff --git a/src/sentry/tasks/seer/context_engine_index.py b/src/sentry/tasks/seer/context_engine_index.py
new file mode 100644
index 00000000000000..ce4a3386e89ff6
--- /dev/null
+++ b/src/sentry/tasks/seer/context_engine_index.py
@@ -0,0 +1,299 @@
+from __future__ import annotations
+
+import logging
+from datetime import UTC, datetime, timedelta, timezone
+
+import sentry_sdk
+from taskbroker_client.retry import Retry
+
+from sentry import features, options
+from sentry.constants import ObjectStatus
+from sentry.models.organization import Organization
+from sentry.models.project import Project
+from sentry.search.events.types import SnubaParams
+from sentry.seer.explorer.context_engine_utils import (
+ EVENT_COUNT_LOOKBACK_DAYS,
+ ProjectEventCounts,
+ get_event_counts_for_org_projects,
+ get_instrumentation_types,
+ get_sdk_names_for_org_projects,
+ get_top_span_ops_for_org_projects,
+ get_top_transactions_for_org_projects,
+)
+from sentry.seer.explorer.explorer_service_map_utils import (
+ _build_nodes,
+ _query_service_dependencies,
+ _send_to_seer,
+)
+from sentry.seer.models import SeerApiError
+from sentry.seer.signed_seer_api import (
+ ExplorerIndexSentryKnowledgeRequest,
+ OrgProjectKnowledgeIndexRequest,
+ OrgProjectKnowledgeProjectData,
+ SeerViewerContext,
+ make_index_sentry_knowledge_request,
+ make_org_project_knowledge_index_request,
+)
+from sentry.tasks.base import instrumented_task
+from sentry.taskworker.namespaces import seer_tasks
+from sentry.utils.hashlib import md5_text
+from sentry.utils.query import RangeQuerySetWrapper
+from sentry.utils.snuba_rpc import SnubaRPCRateLimitExceeded
+
+logger = logging.getLogger(__name__)
+
+
+@instrumented_task(
+ name="sentry.tasks.context_engine_index.index_org_project_knowledge",
+ namespace=seer_tasks,
+ processing_deadline_duration=10 * 60,
+)
+def index_org_project_knowledge(org_id: int) -> None:
+ """
+ For a given org, list active projects, assemble project metadata and call
+ the Seer endpoint to generate LLM summaries and embeddings.
+ """
+ if not options.get("explorer.context_engine_indexing.enable"):
+ logger.info("explorer.context_engine_indexing.enable flag is disabled")
+ return
+
+ projects = list(
+ Project.objects.filter(organization_id=org_id, status=ObjectStatus.ACTIVE).select_related(
+ "organization"
+ )
+ )
+ if not projects:
+ logger.warning(
+ "No projects found for index_org_project_knowledge",
+ extra={"org_id": org_id},
+ )
+ return
+
+ end = datetime.now(UTC)
+ start = end - timedelta(days=EVENT_COUNT_LOOKBACK_DAYS)
+
+ project_ids = [p.id for p in projects]
+ event_counts = get_event_counts_for_org_projects(org_id, project_ids, start, end)
+ high_volume_projects = [p for p in projects if p.id in event_counts]
+ if not high_volume_projects:
+ logger.info(
+ "No high-volume projects found for index_org_project_knowledge",
+ extra={"org_id": org_id, "num_projects": len(projects)},
+ )
+ return
+
+ with sentry_sdk.start_span(op="explorer.context_engine.get_top_transactions_for_org_projects"):
+ transactions_by_project = get_top_transactions_for_org_projects(
+ high_volume_projects, start, end
+ )
+ with sentry_sdk.start_span(op="explorer.context_engine.get_top_span_ops_for_org_projects"):
+ span_ops_by_project = get_top_span_ops_for_org_projects(high_volume_projects, start, end)
+ with sentry_sdk.start_span(op="explorer.context_engine.get_sdk_names_for_org_projects"):
+ sdk_names_by_project = get_sdk_names_for_org_projects(high_volume_projects, start, end)
+
+ project_data: list[OrgProjectKnowledgeProjectData] = []
+ for project in high_volume_projects:
+ counts = event_counts.get(project.id, ProjectEventCounts())
+ project_data.append(
+ OrgProjectKnowledgeProjectData(
+ project_id=project.id,
+ slug=project.slug,
+ sdk_name=sdk_names_by_project.get(project.id, ""),
+ error_count=counts.error_count,
+ transaction_count=counts.transaction_count,
+ instrumentation=get_instrumentation_types(project),
+ top_transactions=transactions_by_project.get(project.id, []),
+ top_span_operations=span_ops_by_project.get(project.id, []),
+ )
+ )
+
+ payload = OrgProjectKnowledgeIndexRequest(org_id=org_id, projects=project_data)
+
+ viewer_context = SeerViewerContext(organization_id=org_id)
+
+ try:
+ response = make_org_project_knowledge_index_request(
+ payload,
+ timeout=30,
+ viewer_context=viewer_context,
+ )
+ if response.status >= 400:
+ raise SeerApiError("Seer request failed", response.status)
+ except Exception:
+ logger.exception(
+ "Failed to call Seer org-project-knowledge endpoint",
+ extra={"org_id": org_id, "num_projects": len(project_data)},
+ )
+ raise
+
+ logger.info(
+ "Successfully called Seer org-project-knowledge endpoint",
+ extra={"org_id": org_id, "num_projects": len(project_data)},
+ )
+
+
+@instrumented_task(
+ name="sentry.tasks.context_engine_index.build_service_map",
+ namespace=seer_tasks,
+ processing_deadline_duration=10 * 60, # 10 minutes
+ retry=Retry(times=3, on=(SnubaRPCRateLimitExceeded,), delay=60),
+)
+def build_service_map(organization_id: int, *args, **kwargs) -> None:
+ """
+ Build service map for a single organization and send to Seer.
+
+ This task:
+ 1. Checks feature flags
+ 2. Queries Snuba for service dependencies
+ 3. Classifies service roles using graph analysis
+ 4. Sends data to Seer
+
+ Args:
+ organization_id: Organization ID to build map for
+ """
+ if not options.get("explorer.context_engine_indexing.enable"):
+ logger.info("explorer.context_engine_indexing.enable flag is disabled")
+ return
+
+ logger.info(
+ "Starting service map build",
+ extra={"org_id": organization_id},
+ )
+
+ try:
+ organization = Organization.objects.get(id=organization_id)
+ projects = list(
+ Project.objects.filter(organization_id=organization_id, status=ObjectStatus.ACTIVE)
+ )
+
+ if not projects:
+ logger.info("No projects found for organization", extra={"org_id": organization_id})
+ return
+
+ end = datetime.now(timezone.utc)
+ start = end - timedelta(hours=24)
+
+ snuba_params = SnubaParams(
+ start=start,
+ end=end,
+ projects=projects,
+ organization=organization,
+ )
+
+ edges = _query_service_dependencies(snuba_params)
+ nodes = _build_nodes(edges, projects)
+
+ if not nodes:
+ logger.info("No service map data found", extra={"org_id": organization_id})
+ return
+
+ _send_to_seer(organization_id, nodes, edges)
+
+ logger.info(
+ "Successfully completed service map build",
+ extra={
+ "org_id": organization_id,
+ "edge_count": len(edges),
+ "node_count": len(nodes),
+ },
+ )
+
+ except Organization.DoesNotExist:
+ logger.error("Organization not found", extra={"org_id": organization_id})
+ return
+ except Exception:
+ sentry_sdk.capture_exception()
+ logger.exception(
+ "Failed to build service map",
+ extra={"org_id": organization_id},
+ )
+ raise
+
+
+def get_allowed_org_ids_context_engine_indexing() -> list[int]:
+ """
+ Get the list of allowed organizations for context engine indexing.
+
+ Divides all active orgs into 24 buckets via md5 hash of org ID. Only the bucket matching the current
+ hour is checked for the seer-explorer-context-engine feature flag, keeping feature check
+ volume at ~1/24th of total orgs.
+ """
+ with sentry_sdk.start_span(
+ op="explorer.context_engine.get_allowed_org_ids_context_engine_indexing"
+ ):
+ now = datetime.now(UTC)
+ TOTAL_HOURLY_SLOTS = 24
+
+ eligible_org_ids: list[int] = []
+
+ for org in RangeQuerySetWrapper(
+ Organization.objects.filter(status=ObjectStatus.ACTIVE),
+ result_value_getter=lambda o: o.id,
+ ):
+ # Ordering of these if blocks is very crucial. We want to check the hour first as
+ # checking the feature flag is an expensive operation and we want to avoid it if possible.
+ if int(md5_text(str(org.id)).hexdigest(), 16) % TOTAL_HOURLY_SLOTS == now.hour:
+ with sentry_sdk.start_span(op="explorer.context_engine.has_feature"):
+ if features.has("organizations:seer-explorer-context-engine", org):
+ eligible_org_ids.append(org.id)
+
+ return eligible_org_ids
+
+
+@instrumented_task(
+ name="sentry.tasks.context_engine_index.schedule_context_engine_indexing_tasks",
+ namespace=seer_tasks,
+ processing_deadline_duration=30 * 60,
+)
+def schedule_context_engine_indexing_tasks() -> None:
+ """
+ Schedule context engine indexing tasks for all allowed organizations.
+
+ Dispatches index_org_project_knowledge and build_service_map for each org
+ with the seer-explorer-context-engine feature flag enabled.
+ """
+ if not options.get("explorer.context_engine_indexing.enable"):
+ logger.info("explorer.context_engine_indexing.enable flag is disabled")
+ return
+
+ allowed_org_ids = get_allowed_org_ids_context_engine_indexing()
+
+ dispatched = 0
+ for org_id in allowed_org_ids:
+ try:
+ index_org_project_knowledge.apply_async(args=[org_id])
+ build_service_map.apply_async(args=[org_id])
+ dispatched += 1
+ except Exception:
+ logger.exception(
+ "Failed to dispatch context engine tasks for org",
+ extra={"org_id": org_id},
+ )
+
+ logger.info(
+ "Scheduled context engine indexing tasks",
+ extra={
+ "orgs": allowed_org_ids[:10],
+ "total_org_count": len(allowed_org_ids),
+ "dispatched": dispatched,
+ },
+ )
+
+
+@instrumented_task(
+ name="sentry.tasks.context_engine_index.index_sentry_knowledge",
+ namespace=seer_tasks,
+ processing_deadline_duration=30,
+)
+def index_sentry_knowledge() -> None:
+ response = make_index_sentry_knowledge_request(
+ body=ExplorerIndexSentryKnowledgeRequest(replace_existing=True)
+ )
+
+ if response.status >= 400:
+ raise Exception(
+ f"Seer sentry-knowledge endpoint returned {response.status}: {response.data.decode()}"
+ )
+
+ logger.info("Successfully called Seer sentry-knowledge endpoint")
+ return None
diff --git a/src/sentry/tasks/delete_seer_grouping_records.py b/src/sentry/tasks/seer/delete_seer_grouping_records.py
similarity index 100%
rename from src/sentry/tasks/delete_seer_grouping_records.py
rename to src/sentry/tasks/seer/delete_seer_grouping_records.py
diff --git a/src/sentry/tasks/seer_explorer_index.py b/src/sentry/tasks/seer/explorer_index.py
similarity index 100%
rename from src/sentry/tasks/seer_explorer_index.py
rename to src/sentry/tasks/seer/explorer_index.py
diff --git a/tests/sentry/api/helpers/test_group_index.py b/tests/sentry/api/helpers/test_group_index.py
index e6a6208d5f2675..327d98130e7307 100644
--- a/tests/sentry/api/helpers/test_group_index.py
+++ b/tests/sentry/api/helpers/test_group_index.py
@@ -1192,7 +1192,7 @@ def test_delete_groups_simple(self, send_robust: Mock) -> None:
assert send_robust.called
@patch(
- "sentry.tasks.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
+ "sentry.tasks.seer.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
)
@patch("sentry.signals.issue_deleted.send_robust")
def test_delete_groups_deletes_seer_records_by_hash(
diff --git a/tests/sentry/core/endpoints/test_project_details.py b/tests/sentry/core/endpoints/test_project_details.py
index ba3bd9c750e866..03d942a44d248a 100644
--- a/tests/sentry/core/endpoints/test_project_details.py
+++ b/tests/sentry/core/endpoints/test_project_details.py
@@ -1631,7 +1631,7 @@ def test_internal_project(self) -> None:
).exists()
@mock.patch(
- "sentry.tasks.delete_seer_grouping_records.call_seer_delete_project_grouping_records.apply_async"
+ "sentry.tasks.seer.delete_seer_grouping_records.call_seer_delete_project_grouping_records.apply_async"
)
def test_delete_project_and_delete_grouping_records(
self, mock_call_seer_delete_project_grouping_records
diff --git a/tests/sentry/deletions/test_group.py b/tests/sentry/deletions/test_group.py
index 44cce90332d191..f4efe111121274 100644
--- a/tests/sentry/deletions/test_group.py
+++ b/tests/sentry/deletions/test_group.py
@@ -184,7 +184,7 @@ def test_cleanup(self, nodestore_delete_multi: mock.Mock) -> None:
del os.environ["_SENTRY_CLEANUP"]
@mock.patch(
- "sentry.tasks.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
+ "sentry.tasks.seer.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
)
def test_delete_groups_delete_grouping_records_by_hash(
self, mock_delete_seer_grouping_records_by_hash_apply_async: mock.Mock
@@ -232,7 +232,7 @@ def test_delete_groups_delete_grouping_records_by_hash(
}
@mock.patch(
- "sentry.tasks.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
+ "sentry.tasks.seer.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
)
def test_invalid_group_type_handling(
self, mock_delete_seer_grouping_records_by_hash_apply_async: mock.Mock
diff --git a/tests/sentry/integrations/api/endpoints/test_organization_repository_details.py b/tests/sentry/integrations/api/endpoints/test_organization_repository_details.py
index 740804602fc289..9a99c805c212e4 100644
--- a/tests/sentry/integrations/api/endpoints/test_organization_repository_details.py
+++ b/tests/sentry/integrations/api/endpoints/test_organization_repository_details.py
@@ -272,7 +272,7 @@ def test_put_cancel_deletion(self) -> None:
organization_id=org.id, key=build_pending_deletion_key(repo)
).exists()
- @patch("sentry.tasks.seer.cleanup_seer_repository_preferences.apply_async")
+ @patch("sentry.tasks.seer.cleanup.cleanup_seer_repository_preferences.apply_async")
def test_put_hide_repo(self, mock_cleanup_task: MagicMock) -> None:
self.login_as(user=self.user)
@@ -303,7 +303,7 @@ def test_put_hide_repo(self, mock_cleanup_task: MagicMock) -> None:
}
)
- @patch("sentry.tasks.seer.cleanup_seer_repository_preferences.apply_async")
+ @patch("sentry.tasks.seer.cleanup.cleanup_seer_repository_preferences.apply_async")
def test_put_hide_repo_with_commits(self, mock_cleanup_task: MagicMock) -> None:
self.login_as(user=self.user)
@@ -364,7 +364,7 @@ def test_put_bad_integration_id(self) -> None:
assert response.data == {"integrationId": ["A valid integer is required."]}
assert Repository.objects.get(id=repo.id).name == "example"
- @patch("sentry.tasks.seer.cleanup_seer_repository_preferences.apply_async")
+ @patch("sentry.tasks.seer.cleanup.cleanup_seer_repository_preferences.apply_async")
def test_put_hide_repo_triggers_cleanup(self, mock_cleanup_task: MagicMock) -> None:
"""Test that hiding a repository triggers Seer cleanup task."""
self.login_as(user=self.user)
@@ -395,7 +395,7 @@ def test_put_hide_repo_triggers_cleanup(self, mock_cleanup_task: MagicMock) -> N
}
)
- @patch("sentry.tasks.seer.cleanup_seer_repository_preferences.apply_async")
+ @patch("sentry.tasks.seer.cleanup.cleanup_seer_repository_preferences.apply_async")
def test_put_hide_repo_no_cleanup_when_null_fields(self, mock_cleanup_task: MagicMock) -> None:
"""Test that hiding a repository with null external_id/provider does not trigger Seer cleanup."""
self.login_as(user=self.user)
@@ -420,7 +420,7 @@ def test_put_hide_repo_no_cleanup_when_null_fields(self, mock_cleanup_task: Magi
# Verify the cleanup task was NOT called
mock_cleanup_task.assert_not_called()
- @patch("sentry.tasks.seer.cleanup_seer_repository_preferences.apply_async")
+ @patch("sentry.tasks.seer.cleanup.cleanup_seer_repository_preferences.apply_async")
def test_put_hide_repo_no_cleanup_when_external_id_null(
self, mock_cleanup_task: MagicMock
) -> None:
@@ -447,7 +447,7 @@ def test_put_hide_repo_no_cleanup_when_external_id_null(
# Verify the cleanup task was NOT called
mock_cleanup_task.assert_not_called()
- @patch("sentry.tasks.seer.cleanup_seer_repository_preferences.apply_async")
+ @patch("sentry.tasks.seer.cleanup.cleanup_seer_repository_preferences.apply_async")
def test_put_hide_repo_no_cleanup_when_provider_null(
self, mock_cleanup_task: MagicMock
) -> None:
diff --git a/tests/sentry/seer/autofix/test_autofix.py b/tests/sentry/seer/autofix/test_autofix.py
index 5292fbcc704fe7..1b12f91f7a0d44 100644
--- a/tests/sentry/seer/autofix/test_autofix.py
+++ b/tests/sentry/seer/autofix/test_autofix.py
@@ -828,7 +828,7 @@ def setUp(self) -> None:
@patch("sentry.seer.autofix.autofix._get_profile_from_trace_tree")
@patch("sentry.seer.autofix.autofix._get_trace_tree_for_event")
@patch("sentry.seer.autofix.autofix._call_autofix")
- @patch("sentry.tasks.autofix.check_autofix_status.apply_async")
+ @patch("sentry.tasks.seer.autofix.check_autofix_status.apply_async")
def test_trigger_autofix_with_event_id(
self,
mock_check_autofix_status,
@@ -934,7 +934,7 @@ def test_trigger_autofix_without_event_id_no_events(
@patch("sentry.seer.autofix.autofix._get_profile_from_trace_tree")
@patch("sentry.seer.autofix.autofix._get_trace_tree_for_event")
@patch("sentry.seer.autofix.autofix._call_autofix")
- @patch("sentry.tasks.autofix.check_autofix_status.apply_async")
+ @patch("sentry.tasks.seer.autofix.check_autofix_status.apply_async")
def test_trigger_autofix_with_web_vitals_issue(
self,
mock_check_autofix_status,
diff --git a/tests/sentry/seer/endpoints/test_group_ai_autofix.py b/tests/sentry/seer/endpoints/test_group_ai_autofix.py
index 909fcdead0bf20..aa9d4f008228bc 100644
--- a/tests/sentry/seer/endpoints/test_group_ai_autofix.py
+++ b/tests/sentry/seer/endpoints/test_group_ai_autofix.py
@@ -313,7 +313,7 @@ def __init__(self):
@patch("sentry.seer.autofix.autofix._get_profile_from_trace_tree")
@patch("sentry.seer.autofix.autofix._call_autofix")
@patch("sentry.seer.autofix.autofix._get_trace_tree_for_event")
- @patch("sentry.tasks.autofix.check_autofix_status.apply_async")
+ @patch("sentry.tasks.seer.autofix.check_autofix_status.apply_async")
def test_ai_autofix_post_endpoint(
self,
mock_check_autofix_status,
@@ -399,7 +399,7 @@ def test_ai_autofix_post_endpoint(
@patch("sentry.seer.autofix.autofix._get_profile_from_trace_tree")
@patch("sentry.seer.autofix.autofix._call_autofix")
@patch("sentry.seer.autofix.autofix._get_trace_tree_for_event")
- @patch("sentry.tasks.autofix.check_autofix_status.apply_async")
+ @patch("sentry.tasks.seer.autofix.check_autofix_status.apply_async")
def test_ai_autofix_post_without_code_mappings(
self,
mock_check_autofix_status,
@@ -468,7 +468,7 @@ def test_ai_autofix_post_without_code_mappings(
@patch("sentry.seer.autofix.autofix._get_profile_from_trace_tree")
@patch("sentry.seer.autofix.autofix._call_autofix")
@patch("sentry.seer.autofix.autofix._get_trace_tree_for_event")
- @patch("sentry.tasks.autofix.check_autofix_status.apply_async")
+ @patch("sentry.tasks.seer.autofix.check_autofix_status.apply_async")
def test_ai_autofix_post_without_event_id(
self,
mock_check_autofix_status,
@@ -552,7 +552,7 @@ def test_ai_autofix_post_without_event_id(
@patch("sentry.seer.explorer.utils.get_from_profiling_service")
@patch("sentry.seer.autofix.autofix._call_autofix")
@patch("sentry.seer.autofix.autofix._get_trace_tree_for_event")
- @patch("sentry.tasks.autofix.check_autofix_status.apply_async")
+ @patch("sentry.tasks.seer.autofix.check_autofix_status.apply_async")
def test_ai_autofix_post_without_event_id_no_recommended_event(
self,
mock_check_autofix_status,
@@ -936,7 +936,7 @@ def test_stopping_point(self, mock_trigger_explorer):
@patch("sentry.seer.autofix.autofix._call_autofix")
@patch("sentry.seer.autofix.autofix._get_trace_tree_for_event")
- @patch("sentry.tasks.autofix.check_autofix_status.apply_async")
+ @patch("sentry.tasks.seer.autofix.check_autofix_status.apply_async")
def test_post_routes_to_legacy_with_mode_param(
self,
mock_check_autofix_status,
diff --git a/tests/sentry/seer/explorer/test_explorer_service_map_utils.py b/tests/sentry/seer/explorer/test_explorer_service_map_utils.py
index 5f7e4df3569d40..deea917620056e 100644
--- a/tests/sentry/seer/explorer/test_explorer_service_map_utils.py
+++ b/tests/sentry/seer/explorer/test_explorer_service_map_utils.py
@@ -18,7 +18,7 @@
_query_service_dependencies,
_send_to_seer,
)
-from sentry.tasks.context_engine_index import build_service_map
+from sentry.tasks.seer.context_engine_index import build_service_map
from sentry.testutils.cases import SnubaTestCase, SpanTestCase, TestCase
from sentry.testutils.helpers.datetime import before_now
from sentry.testutils.helpers.options import override_options
@@ -129,14 +129,14 @@ def test_handles_no_projects(self):
with override_options({"explorer.context_engine_indexing.enable": True}):
with mock.patch(
- "sentry.tasks.context_engine_index._query_service_dependencies"
+ "sentry.tasks.seer.context_engine_index._query_service_dependencies"
) as mock_query:
build_service_map(org.id)
mock_query.assert_not_called()
- @mock.patch("sentry.tasks.context_engine_index._send_to_seer")
- @mock.patch("sentry.tasks.context_engine_index._query_service_dependencies")
+ @mock.patch("sentry.tasks.seer.context_engine_index._send_to_seer")
+ @mock.patch("sentry.tasks.seer.context_engine_index._query_service_dependencies")
def test_complete_workflow(self, mock_dependencies, mock_send):
org = self.create_organization()
project1 = self.create_project(organization=org)
@@ -160,8 +160,8 @@ def test_complete_workflow(self, mock_dependencies, mock_send):
assert isinstance(snuba_params, SnubaParams)
mock_send.assert_called_once()
- @mock.patch("sentry.tasks.context_engine_index._build_nodes")
- @mock.patch("sentry.tasks.context_engine_index._query_service_dependencies")
+ @mock.patch("sentry.tasks.seer.context_engine_index._build_nodes")
+ @mock.patch("sentry.tasks.seer.context_engine_index._query_service_dependencies")
def test_handles_no_nodes(self, mock_dependencies, mock_build_nodes):
org = self.create_organization()
self.create_project(organization=org)
@@ -170,12 +170,12 @@ def test_handles_no_nodes(self, mock_dependencies, mock_build_nodes):
mock_build_nodes.return_value = []
with override_options({"explorer.context_engine_indexing.enable": True}):
- with mock.patch("sentry.tasks.context_engine_index._send_to_seer") as mock_send:
+ with mock.patch("sentry.tasks.seer.context_engine_index._send_to_seer") as mock_send:
build_service_map(org.id)
mock_send.assert_not_called()
- @mock.patch("sentry.tasks.context_engine_index._query_service_dependencies")
+ @mock.patch("sentry.tasks.seer.context_engine_index._query_service_dependencies")
def test_handles_exception(self, mock_dependencies):
org = self.create_organization()
@@ -1146,7 +1146,7 @@ def test_complete_workflow_realistic_topology(self):
self.store_spans(spans)
- with mock.patch("sentry.tasks.context_engine_index._send_to_seer") as mock_send:
+ with mock.patch("sentry.tasks.seer.context_engine_index._send_to_seer") as mock_send:
with override_options(
{
"explorer.context_engine_indexing.enable": True,
diff --git a/tests/sentry/tasks/seer/__init__.py b/tests/sentry/tasks/seer/__init__.py
new file mode 100644
index 00000000000000..e69de29bb2d1d6
diff --git a/tests/sentry/tasks/test_autofix.py b/tests/sentry/tasks/seer/test_autofix.py
similarity index 87%
rename from tests/sentry/tasks/test_autofix.py
rename to tests/sentry/tasks/seer/test_autofix.py
index e411a5f3127343..20566413060f75 100644
--- a/tests/sentry/tasks/test_autofix.py
+++ b/tests/sentry/tasks/seer/test_autofix.py
@@ -9,7 +9,7 @@
from sentry.seer.autofix.utils import AutofixState, get_seer_seat_based_tier_cache_key
from sentry.seer.models import SeerApiError, SummarizeIssueResponse, SummarizeIssueScores
from sentry.seer.models.project_repository import SeerProjectRepository
-from sentry.tasks.autofix import (
+from sentry.tasks.seer.autofix import (
check_autofix_status,
configure_seer_for_existing_org,
generate_issue_summary_only,
@@ -19,8 +19,8 @@
class TestCheckAutofixStatus(TestCase):
- @patch("sentry.tasks.autofix.get_autofix_state")
- @patch("sentry.tasks.autofix.logger.error")
+ @patch("sentry.tasks.seer.autofix.get_autofix_state")
+ @patch("sentry.tasks.seer.autofix.logger.error")
def test_check_autofix_status_processing_too_long(
self, mock_logger: MagicMock, mock_get_autofix_state: MagicMock
) -> None:
@@ -45,8 +45,8 @@ def test_check_autofix_status_processing_too_long(
"Autofix run has been processing for more than 5 minutes", extra={"run_id": 123}
)
- @patch("sentry.tasks.autofix.get_autofix_state")
- @patch("sentry.tasks.autofix.logger.error")
+ @patch("sentry.tasks.seer.autofix.get_autofix_state")
+ @patch("sentry.tasks.seer.autofix.logger.error")
def test_check_autofix_status_processing_within_time_limit(
self, mock_logger, mock_get_autofix_state
):
@@ -69,8 +69,8 @@ def test_check_autofix_status_processing_within_time_limit(
# Check that the logger.error was not called
mock_logger.assert_not_called()
- @patch("sentry.tasks.autofix.get_autofix_state")
- @patch("sentry.tasks.autofix.logger.error")
+ @patch("sentry.tasks.seer.autofix.get_autofix_state")
+ @patch("sentry.tasks.seer.autofix.logger.error")
def test_check_autofix_status_completed(
self, mock_logger: MagicMock, mock_get_autofix_state: MagicMock
) -> None:
@@ -93,8 +93,8 @@ def test_check_autofix_status_completed(
# Check that the logger.error was not called
mock_logger.assert_not_called()
- @patch("sentry.tasks.autofix.get_autofix_state")
- @patch("sentry.tasks.autofix.logger.error")
+ @patch("sentry.tasks.seer.autofix.get_autofix_state")
+ @patch("sentry.tasks.seer.autofix.logger.error")
def test_check_autofix_status_no_state(
self, mock_logger: MagicMock, mock_get_autofix_state: MagicMock
) -> None:
@@ -148,8 +148,8 @@ def test_generates_fixability_score_after_summary(
class TestConfigureSeerForExistingOrg(SentryTestCase):
- @patch("sentry.tasks.autofix.bulk_set_project_preferences")
- @patch("sentry.tasks.autofix.bulk_get_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_set_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_get_project_preferences")
def test_configures_org_and_project_settings(
self, mock_bulk_get: MagicMock, mock_bulk_set: MagicMock
) -> None:
@@ -177,8 +177,8 @@ def test_configures_org_and_project_settings(
mock_bulk_set.assert_called_once()
@pytest.mark.skip("DO NOT override autofix automation tuning off")
- @patch("sentry.tasks.autofix.bulk_set_project_preferences")
- @patch("sentry.tasks.autofix.bulk_get_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_set_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_get_project_preferences")
def test_overrides_autofix_off_to_medium(
self, mock_bulk_get: MagicMock, mock_bulk_set: MagicMock
) -> None:
@@ -195,8 +195,8 @@ def test_overrides_autofix_off_to_medium(
# Scanner should be enabled
assert project.get_option("sentry:seer_scanner_automation") is True
- @patch("sentry.tasks.autofix.bulk_set_project_preferences")
- @patch("sentry.tasks.autofix.bulk_get_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_set_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_get_project_preferences")
def test_skips_projects_with_existing_stopping_point(
self, mock_bulk_get: MagicMock, mock_bulk_set: MagicMock
) -> None:
@@ -214,7 +214,7 @@ def test_skips_projects_with_existing_stopping_point(
# bulk_set should not be called since both projects are skipped
mock_bulk_set.assert_not_called()
- @patch("sentry.tasks.autofix.bulk_get_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_get_project_preferences")
def test_raises_on_bulk_get_api_failure(self, mock_bulk_get: MagicMock) -> None:
"""Test that task raises on bulk GET API failure to trigger retry."""
project1 = self.create_project(organization=self.organization)
@@ -229,8 +229,8 @@ def test_raises_on_bulk_get_api_failure(self, mock_bulk_get: MagicMock) -> None:
assert project1.get_option("sentry:seer_scanner_automation") is True
assert project2.get_option("sentry:seer_scanner_automation") is True
- @patch("sentry.tasks.autofix.bulk_set_project_preferences")
- @patch("sentry.tasks.autofix.bulk_get_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_set_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_get_project_preferences")
def test_raises_on_bulk_set_api_failure(
self, mock_bulk_get: MagicMock, mock_bulk_set: MagicMock
) -> None:
@@ -248,8 +248,8 @@ def test_raises_on_bulk_set_api_failure(
assert project1.get_option("sentry:seer_scanner_automation") is True
assert project2.get_option("sentry:seer_scanner_automation") is True
- @patch("sentry.tasks.autofix.bulk_set_project_preferences")
- @patch("sentry.tasks.autofix.bulk_get_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_set_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_get_project_preferences")
def test_sets_seat_based_tier_cache_to_true(
self, mock_bulk_get: MagicMock, mock_bulk_set: MagicMock
) -> None:
@@ -267,9 +267,9 @@ def test_sets_seat_based_tier_cache_to_true(
# Cache should be set to True to prevent race conditions
assert cache.get(cache_key) is True
- @patch("sentry.tasks.autofix.get_autofix_repos_from_project_code_mappings")
- @patch("sentry.tasks.autofix.bulk_set_project_preferences")
- @patch("sentry.tasks.autofix.bulk_get_project_preferences")
+ @patch("sentry.tasks.seer.autofix.get_autofix_repos_from_project_code_mappings")
+ @patch("sentry.tasks.seer.autofix.bulk_set_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_get_project_preferences")
def test_uses_code_mappings_when_no_existing_preferences(
self, mock_bulk_get: MagicMock, mock_bulk_set: MagicMock, mock_get_code_mappings: MagicMock
) -> None:
@@ -285,9 +285,9 @@ def test_uses_code_mappings_when_no_existing_preferences(
preferences = mock_bulk_set.call_args[0][1]
assert preferences[0]["repositories"] == mock_repos
- @patch("sentry.tasks.autofix.get_autofix_repos_from_project_code_mappings")
- @patch("sentry.tasks.autofix.bulk_set_project_preferences")
- @patch("sentry.tasks.autofix.bulk_get_project_preferences")
+ @patch("sentry.tasks.seer.autofix.get_autofix_repos_from_project_code_mappings")
+ @patch("sentry.tasks.seer.autofix.bulk_set_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_get_project_preferences")
def test_preserves_existing_repositories_when_preferences_exist(
self, mock_bulk_get: MagicMock, mock_bulk_set: MagicMock, mock_get_code_mappings: MagicMock
) -> None:
@@ -302,8 +302,8 @@ def test_preserves_existing_repositories_when_preferences_exist(
preferences = mock_bulk_set.call_args[0][1]
assert preferences[0]["repositories"] == existing_repos
- @patch("sentry.tasks.autofix.bulk_set_project_preferences")
- @patch("sentry.tasks.autofix.bulk_get_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_set_project_preferences")
+ @patch("sentry.tasks.seer.autofix.bulk_get_project_preferences")
def test_creates_seer_project_repository(
self, mock_bulk_get: MagicMock, mock_bulk_set: MagicMock
) -> None:
diff --git a/tests/sentry/tasks/test_seer.py b/tests/sentry/tasks/seer/test_cleanup.py
similarity index 89%
rename from tests/sentry/tasks/test_seer.py
rename to tests/sentry/tasks/seer/test_cleanup.py
index 8b2eace7af651d..d84be739fadff6 100644
--- a/tests/sentry/tasks/test_seer.py
+++ b/tests/sentry/tasks/seer/test_cleanup.py
@@ -5,7 +5,7 @@
import pytest
from sentry.seer.models import SeerApiError
-from sentry.tasks.seer import cleanup_seer_repository_preferences
+from sentry.tasks.seer.cleanup import cleanup_seer_repository_preferences
from sentry.testutils.cases import TestCase
@@ -16,7 +16,7 @@ def setUp(self) -> None:
self.repo_external_id = "12345"
self.repo_provider = "github"
- @patch("sentry.tasks.seer.make_remove_repository_request")
+ @patch("sentry.tasks.seer.cleanup.make_remove_repository_request")
def test_cleanup_seer_repository_preferences_success(self, mock_request: MagicMock) -> None:
"""Test successful cleanup of Seer repository preferences."""
mock_request.return_value.status = 200
@@ -35,7 +35,7 @@ def test_cleanup_seer_repository_preferences_success(self, mock_request: MagicMo
"repo_external_id": self.repo_external_id,
}
- @patch("sentry.tasks.seer.make_remove_repository_request")
+ @patch("sentry.tasks.seer.cleanup.make_remove_repository_request")
def test_cleanup_seer_repository_preferences_api_error(self, mock_request: MagicMock) -> None:
"""Test handling of Seer API errors."""
mock_request.return_value.status = 500
@@ -47,7 +47,7 @@ def test_cleanup_seer_repository_preferences_api_error(self, mock_request: Magic
repo_provider=self.repo_provider,
)
- @patch("sentry.tasks.seer.make_remove_repository_request")
+ @patch("sentry.tasks.seer.cleanup.make_remove_repository_request")
def test_cleanup_seer_repository_preferences_organization_not_found(
self, mock_request: MagicMock
) -> None:
diff --git a/tests/sentry/tasks/test_context_engine_index.py b/tests/sentry/tasks/seer/test_context_engine_index.py
similarity index 79%
rename from tests/sentry/tasks/test_context_engine_index.py
rename to tests/sentry/tasks/seer/test_context_engine_index.py
index b9262eab5dbb3d..be2a02d76de0a6 100644
--- a/tests/sentry/tasks/test_context_engine_index.py
+++ b/tests/sentry/tasks/seer/test_context_engine_index.py
@@ -3,7 +3,7 @@
import pytest
from sentry.seer.explorer.context_engine_utils import ProjectEventCounts
-from sentry.tasks.context_engine_index import (
+from sentry.tasks.seer.context_engine_index import (
get_allowed_org_ids_context_engine_indexing,
index_org_project_knowledge,
schedule_context_engine_indexing_tasks,
@@ -28,7 +28,7 @@ def test_returns_early_when_no_projects_found(self):
org_without_projects = self.create_organization()
with override_options({"explorer.context_engine_indexing.enable": True}):
with mock.patch(
- "sentry.tasks.context_engine_index.get_event_counts_for_org_projects"
+ "sentry.tasks.seer.context_engine_index.get_event_counts_for_org_projects"
) as mock_counts:
index_org_project_knowledge(org_without_projects.id)
mock_counts.assert_not_called()
@@ -36,16 +36,16 @@ def test_returns_early_when_no_projects_found(self):
def test_returns_early_when_no_high_volume_projects(self):
with override_options({"explorer.context_engine_indexing.enable": True}):
with mock.patch(
- "sentry.tasks.context_engine_index.get_event_counts_for_org_projects",
+ "sentry.tasks.seer.context_engine_index.get_event_counts_for_org_projects",
return_value={},
):
with mock.patch(
- "sentry.tasks.context_engine_index.make_org_project_knowledge_index_request"
+ "sentry.tasks.seer.context_engine_index.make_org_project_knowledge_index_request"
) as mock_request:
index_org_project_knowledge(self.org.id)
mock_request.assert_not_called()
- @mock.patch("sentry.tasks.context_engine_index.make_org_project_knowledge_index_request")
+ @mock.patch("sentry.tasks.seer.context_engine_index.make_org_project_knowledge_index_request")
def test_calls_seer_endpoint_with_correct_payload(self, mock_request):
mock_request.return_value.status = 200
@@ -55,19 +55,19 @@ def test_calls_seer_endpoint_with_correct_payload(self, mock_request):
with override_options({"explorer.context_engine_indexing.enable": True}):
with mock.patch(
- "sentry.tasks.context_engine_index.get_event_counts_for_org_projects",
+ "sentry.tasks.seer.context_engine_index.get_event_counts_for_org_projects",
return_value=event_counts,
):
with mock.patch(
- "sentry.tasks.context_engine_index.get_top_transactions_for_org_projects",
+ "sentry.tasks.seer.context_engine_index.get_top_transactions_for_org_projects",
return_value={self.project.id: ["GET /api/0/projects/"]},
):
with mock.patch(
- "sentry.tasks.context_engine_index.get_top_span_ops_for_org_projects",
+ "sentry.tasks.seer.context_engine_index.get_top_span_ops_for_org_projects",
return_value={self.project.id: [("db", "SELECT * FROM table")]},
):
with mock.patch(
- "sentry.tasks.context_engine_index.get_sdk_names_for_org_projects",
+ "sentry.tasks.seer.context_engine_index.get_sdk_names_for_org_projects",
return_value={self.project.id: "sentry.python"},
):
index_org_project_knowledge(self.org.id)
@@ -88,27 +88,27 @@ def test_calls_seer_endpoint_with_correct_payload(self, mock_request):
assert project_payload["top_transactions"] == ["GET /api/0/projects/"]
assert project_payload["top_span_operations"] == [("db", "SELECT * FROM table")]
- @mock.patch("sentry.tasks.context_engine_index.make_org_project_knowledge_index_request")
+ @mock.patch("sentry.tasks.seer.context_engine_index.make_org_project_knowledge_index_request")
def test_raises_on_seer_error(self, mock_request):
mock_request.return_value.status = 500
with override_options({"explorer.context_engine_indexing.enable": True}):
with mock.patch(
- "sentry.tasks.context_engine_index.get_event_counts_for_org_projects",
+ "sentry.tasks.seer.context_engine_index.get_event_counts_for_org_projects",
return_value={
self.project.id: ProjectEventCounts(error_count=5000, transaction_count=2000)
},
):
with mock.patch(
- "sentry.tasks.context_engine_index.get_top_transactions_for_org_projects",
+ "sentry.tasks.seer.context_engine_index.get_top_transactions_for_org_projects",
return_value={},
):
with mock.patch(
- "sentry.tasks.context_engine_index.get_top_span_ops_for_org_projects",
+ "sentry.tasks.seer.context_engine_index.get_top_span_ops_for_org_projects",
return_value={},
):
with mock.patch(
- "sentry.tasks.context_engine_index.get_sdk_names_for_org_projects",
+ "sentry.tasks.seer.context_engine_index.get_sdk_names_for_org_projects",
return_value={},
):
with pytest.raises(Exception):
@@ -132,7 +132,7 @@ def feature_enabled_for_test_orgs(_flag_name: str, org, *args, **kwargs) -> bool
with freeze_time(frozen_time):
with mock.patch(
- "sentry.tasks.context_engine_index.features.has",
+ "sentry.tasks.seer.context_engine_index.features.has",
side_effect=feature_enabled_for_test_orgs,
):
eligible = get_allowed_org_ids_context_engine_indexing()
@@ -178,9 +178,11 @@ def test_returns_empty_when_no_orgs_have_feature_flag(self):
@django_db_all
class TestScheduleContextEngineIndexingTasks(TestCase):
- @mock.patch("sentry.tasks.context_engine_index.build_service_map.apply_async")
- @mock.patch("sentry.tasks.context_engine_index.index_org_project_knowledge.apply_async")
- @mock.patch("sentry.tasks.context_engine_index.get_allowed_org_ids_context_engine_indexing")
+ @mock.patch("sentry.tasks.seer.context_engine_index.build_service_map.apply_async")
+ @mock.patch("sentry.tasks.seer.context_engine_index.index_org_project_knowledge.apply_async")
+ @mock.patch(
+ "sentry.tasks.seer.context_engine_index.get_allowed_org_ids_context_engine_indexing"
+ )
def test_dispatches_for_allowed_orgs(self, mock_get_orgs, mock_index, mock_build):
org1 = self.create_organization()
org2 = self.create_organization()
@@ -198,8 +200,8 @@ def test_dispatches_for_allowed_orgs(self, mock_get_orgs, mock_index, mock_build
dispatched_index_ids = [c[1]["args"][0] for c in mock_index.call_args_list]
assert dispatched_index_ids == [org1.id, org2.id]
- @mock.patch("sentry.tasks.context_engine_index.build_service_map.apply_async")
- @mock.patch("sentry.tasks.context_engine_index.index_org_project_knowledge.apply_async")
+ @mock.patch("sentry.tasks.seer.context_engine_index.build_service_map.apply_async")
+ @mock.patch("sentry.tasks.seer.context_engine_index.index_org_project_knowledge.apply_async")
def test_noop_when_no_allowed_orgs(self, mock_index, mock_build):
with override_options({"explorer.context_engine_indexing.enable": True}):
schedule_context_engine_indexing_tasks()
diff --git a/tests/sentry/tasks/test_delete_seer_grouping_records.py b/tests/sentry/tasks/seer/test_delete_seer_grouping_records.py
similarity index 89%
rename from tests/sentry/tasks/test_delete_seer_grouping_records.py
rename to tests/sentry/tasks/seer/test_delete_seer_grouping_records.py
index ac8be04ecd7a74..2a57b5dbefc70b 100644
--- a/tests/sentry/tasks/test_delete_seer_grouping_records.py
+++ b/tests/sentry/tasks/seer/test_delete_seer_grouping_records.py
@@ -2,7 +2,7 @@
from unittest.mock import MagicMock, patch
from sentry.models.grouphash import GroupHash
-from sentry.tasks.delete_seer_grouping_records import (
+from sentry.tasks.seer.delete_seer_grouping_records import (
delete_seer_grouping_records_by_hash,
may_schedule_task_to_delete_hashes_from_seer,
)
@@ -28,7 +28,7 @@ def _setup_groups_and_hashes(self, number_of_groups: int = 5) -> list[str]:
return expected_hashes
@patch(
- "sentry.tasks.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
+ "sentry.tasks.seer.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
)
def test_simple(self, mock_apply_async: MagicMock) -> None:
"""
@@ -49,7 +49,7 @@ def test_chunked(self) -> None:
batch_size = 10
with (
patch(
- "sentry.tasks.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
+ "sentry.tasks.seer.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
) as mock_apply_async,
self.options({"embeddings-grouping.seer.delete-record-batch-size": batch_size}),
):
@@ -76,7 +76,7 @@ def test_chunked(self) -> None:
assert second_call_args[2] == 0
@patch(
- "sentry.tasks.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
+ "sentry.tasks.seer.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
)
def test_group_without_hashes(self, mock_apply_async: MagicMock) -> None:
group = self.create_group(project=self.project)
@@ -85,7 +85,7 @@ def test_group_without_hashes(self, mock_apply_async: MagicMock) -> None:
mock_apply_async.assert_not_called()
@patch(
- "sentry.tasks.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
+ "sentry.tasks.seer.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
)
def test_no_group_ids(self, mock_apply_async: MagicMock) -> None:
"""
@@ -95,7 +95,7 @@ def test_no_group_ids(self, mock_apply_async: MagicMock) -> None:
mock_apply_async.assert_not_called()
@patch(
- "sentry.tasks.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
+ "sentry.tasks.seer.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
)
def test_called_task_with_too_many_hashes(self, mock_apply_async: MagicMock) -> None:
"""This tests the built-in logic of spreading hashes across multiple tasks."""
@@ -134,7 +134,7 @@ def test_called_task_with_too_many_hashes(self, mock_apply_async: MagicMock) ->
assert first_chunk + second_chunk + third_chunk == expected_hashes
@patch(
- "sentry.tasks.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
+ "sentry.tasks.seer.delete_seer_grouping_records.delete_seer_grouping_records_by_hash.apply_async"
)
def test_does_not_schedule_task_if_missing_option(self, mock_apply_async: MagicMock) -> None:
"""
diff --git a/tests/sentry/tasks/test_seer_explorer_index.py b/tests/sentry/tasks/seer/test_explorer_index.py
similarity index 95%
rename from tests/sentry/tasks/test_seer_explorer_index.py
rename to tests/sentry/tasks/seer/test_explorer_index.py
index 65339facb26c8e..d2bae689a84425 100644
--- a/tests/sentry/tasks/test_seer_explorer_index.py
+++ b/tests/sentry/tasks/seer/test_explorer_index.py
@@ -6,7 +6,7 @@
from sentry.constants import ObjectStatus
from sentry.models.promptsactivity import PromptsActivity
-from sentry.tasks.seer_explorer_index import (
+from sentry.tasks.seer.explorer_index import (
dispatch_explorer_index_projects,
get_seer_explorer_enabled_projects,
run_explorer_index_for_projects,
@@ -125,7 +125,7 @@ def test_returns_empty_without_feature_flag(self):
}
):
with mock.patch(
- "sentry.tasks.seer_explorer_index.in_rollout_group", return_value=False
+ "sentry.tasks.seer.explorer_index.in_rollout_group", return_value=False
):
result = list(get_seer_explorer_enabled_projects())
@@ -280,7 +280,7 @@ def test_includes_projects_with_legacy_seer_plan_via_rollout(self):
"organizations:seer-added": [org.slug],
}
):
- with mock.patch("sentry.tasks.seer_explorer_index.in_rollout_group", return_value=True):
+ with mock.patch("sentry.tasks.seer.explorer_index.in_rollout_group", return_value=True):
result = list(get_seer_explorer_enabled_projects())
project_ids = [p[0] for p in result]
@@ -308,7 +308,7 @@ def test_includes_projects_with_seat_based_plan_via_rollout(self):
"organizations:seat-based-seer-enabled": [org.slug],
}
):
- with mock.patch("sentry.tasks.seer_explorer_index.in_rollout_group", return_value=True):
+ with mock.patch("sentry.tasks.seer.explorer_index.in_rollout_group", return_value=True):
result = list(get_seer_explorer_enabled_projects())
project_ids = [p[0] for p in result]
@@ -337,7 +337,7 @@ def test_excludes_projects_with_billing_plan_not_in_rollout(self):
}
):
with mock.patch(
- "sentry.tasks.seer_explorer_index.in_rollout_group", return_value=False
+ "sentry.tasks.seer.explorer_index.in_rollout_group", return_value=False
):
result = list(get_seer_explorer_enabled_projects())
@@ -350,7 +350,7 @@ class TestScheduleExplorerIndex(TestCase):
def test_skips_when_option_disabled(self):
with self.options({"seer.explorer_index.enable": False}):
with mock.patch(
- "sentry.tasks.seer_explorer_index.get_seer_explorer_enabled_projects"
+ "sentry.tasks.seer.explorer_index.get_seer_explorer_enabled_projects"
) as mock_get_projects:
schedule_explorer_index()
mock_get_projects.assert_not_called()
@@ -378,7 +378,7 @@ def test_schedules_projects_with_option_enabled(self):
}
):
with mock.patch(
- "sentry.tasks.seer_explorer_index.dispatch_explorer_index_projects"
+ "sentry.tasks.seer.explorer_index.dispatch_explorer_index_projects"
) as mock_dispatch:
mock_dispatch.return_value = iter([])
schedule_explorer_index()
@@ -393,7 +393,7 @@ def test_batches_projects_with_delays(self):
projects = [(i, 1) for i in range(150)]
with mock.patch(
- "sentry.tasks.seer_explorer_index.run_explorer_index_for_projects.apply_async"
+ "sentry.tasks.seer.explorer_index.run_explorer_index_for_projects.apply_async"
) as mock_task:
result = list(dispatch_explorer_index_projects(iter(projects), timestamp))
@@ -410,7 +410,7 @@ def test_batches_projects_with_delays(self):
@django_db_all
class TestRunExplorerIndexForProjects(TestCase):
- @patch("sentry.tasks.seer_explorer_index.make_explorer_index_request")
+ @patch("sentry.tasks.seer.explorer_index.make_explorer_index_request")
def test_calls_seer_endpoint_successfully(self, mock_request):
mock_request.return_value.status = 200
mock_request.return_value.json.return_value = {"scheduled_count": 3, "projects": []}
@@ -429,7 +429,7 @@ def test_calls_seer_endpoint_successfully(self, mock_request):
{"org_id": 200, "project_id": 3},
]
- @patch("sentry.tasks.seer_explorer_index.make_explorer_index_request")
+ @patch("sentry.tasks.seer.explorer_index.make_explorer_index_request")
def test_handles_request_error(self, mock_request):
mock_request.return_value.status = 500
@@ -443,7 +443,7 @@ def test_handles_request_error(self, mock_request):
def test_skips_when_option_disabled(self):
with self.options({"seer.explorer_index.enable": False}):
with mock.patch(
- "sentry.tasks.seer_explorer_index.make_explorer_index_request"
+ "sentry.tasks.seer.explorer_index.make_explorer_index_request"
) as mock_request:
run_explorer_index_for_projects([(1, 100)], "2024-01-15T12:00:00+00:00")
mock_request.assert_not_called()
diff --git a/tests/sentry/tasks/test_post_process.py b/tests/sentry/tasks/test_post_process.py
index 80988620d85315..686d92f62f0c0e 100644
--- a/tests/sentry/tasks/test_post_process.py
+++ b/tests/sentry/tasks/test_post_process.py
@@ -2778,7 +2778,7 @@ def test_skip_process_similarity_global(self, mock_safe_execute: MagicMock) -> N
class KickOffSeerAutomationTestMixin(BasePostProcessGroupMixin):
- @patch("sentry.tasks.autofix.generate_summary_and_run_automation.delay")
+ @patch("sentry.tasks.seer.autofix.generate_summary_and_run_automation.delay")
@with_feature("organizations:gen-ai-features")
def test_kick_off_seer_automation_with_features(self, mock_generate_summary_and_run_automation):
self.project.update_option("sentry:seer_scanner_automation", True)
@@ -2798,7 +2798,7 @@ def test_kick_off_seer_automation_with_features(self, mock_generate_summary_and_
event.group.id, trigger_path="old_seer_automation"
)
- @patch("sentry.tasks.autofix.generate_summary_and_run_automation.delay")
+ @patch("sentry.tasks.seer.autofix.generate_summary_and_run_automation.delay")
def test_kick_off_seer_automation_without_org_feature(
self, mock_generate_summary_and_run_automation
):
@@ -2816,7 +2816,7 @@ def test_kick_off_seer_automation_without_org_feature(
mock_generate_summary_and_run_automation.assert_not_called()
- @patch("sentry.tasks.autofix.generate_summary_and_run_automation.delay")
+ @patch("sentry.tasks.seer.autofix.generate_summary_and_run_automation.delay")
@with_feature("organizations:gen-ai-features")
def test_kick_off_seer_automation_without_scanner_on(
self, mock_generate_summary_and_run_automation
@@ -2837,7 +2837,7 @@ def test_kick_off_seer_automation_without_scanner_on(
mock_generate_summary_and_run_automation.assert_not_called()
- @patch("sentry.tasks.autofix.generate_summary_and_run_automation.delay")
+ @patch("sentry.tasks.seer.autofix.generate_summary_and_run_automation.delay")
@with_feature("organizations:gen-ai-features")
def test_kick_off_seer_automation_skips_existing_fixability_score(
self, mock_generate_summary_and_run_automation
@@ -2862,7 +2862,7 @@ def test_kick_off_seer_automation_skips_existing_fixability_score(
mock_generate_summary_and_run_automation.assert_not_called()
- @patch("sentry.tasks.autofix.generate_summary_and_run_automation.delay")
+ @patch("sentry.tasks.seer.autofix.generate_summary_and_run_automation.delay")
@with_feature("organizations:gen-ai-features")
def test_kick_off_seer_automation_runs_with_missing_fixability_score(
self, mock_generate_summary_and_run_automation
@@ -2888,7 +2888,7 @@ def test_kick_off_seer_automation_runs_with_missing_fixability_score(
group.id, trigger_path="old_seer_automation"
)
- @patch("sentry.tasks.autofix.generate_summary_and_run_automation.delay")
+ @patch("sentry.tasks.seer.autofix.generate_summary_and_run_automation.delay")
@with_feature("organizations:gen-ai-features")
def test_kick_off_seer_automation_skips_with_existing_fixability_score(
self, mock_generate_summary_and_run_automation
@@ -2921,7 +2921,7 @@ def test_kick_off_seer_automation_skips_with_existing_fixability_score(
@patch("sentry.seer.autofix.utils.is_seer_scanner_rate_limited")
@patch("sentry.quotas.backend.check_seer_quota")
- @patch("sentry.tasks.autofix.generate_summary_and_run_automation.delay")
+ @patch("sentry.tasks.seer.autofix.generate_summary_and_run_automation.delay")
@with_feature("organizations:gen-ai-features")
def test_rate_limit_only_checked_after_all_other_checks_pass(
self,
@@ -2992,7 +2992,7 @@ def test_rate_limit_only_checked_after_all_other_checks_pass(
mock_is_rate_limited.assert_not_called()
mock_generate_summary_and_run_automation.assert_not_called()
- @patch("sentry.tasks.autofix.generate_summary_and_run_automation.delay")
+ @patch("sentry.tasks.seer.autofix.generate_summary_and_run_automation.delay")
@with_feature("organizations:gen-ai-features")
def test_kick_off_seer_automation_skips_when_lock_held(
self, mock_generate_summary_and_run_automation
@@ -3041,7 +3041,7 @@ def test_kick_off_seer_automation_skips_when_lock_held(
event2.group.id, trigger_path="old_seer_automation"
)
- @patch("sentry.tasks.autofix.generate_summary_and_run_automation.delay")
+ @patch("sentry.tasks.seer.autofix.generate_summary_and_run_automation.delay")
@with_feature("organizations:gen-ai-features")
def test_kick_off_seer_automation_with_hide_ai_features_enabled(
self, mock_generate_summary_and_run_automation
@@ -3069,7 +3069,7 @@ def test_kick_off_seer_automation_with_hide_ai_features_enabled(
class TriageSignalsV0TestMixin(BasePostProcessGroupMixin):
"""Tests for the triage signals V0 flow."""
- @patch("sentry.tasks.autofix.generate_issue_summary_only.delay")
+ @patch("sentry.tasks.seer.autofix.generate_issue_summary_only.delay")
@with_feature({"organizations:gen-ai-features": True})
def test_triage_signals_event_count_less_than_10_no_cache(
self, mock_generate_summary_only, mock_seat_based_tier
@@ -3097,7 +3097,7 @@ def test_triage_signals_event_count_less_than_10_no_cache(
# Should call generate_issue_summary_only (not generate_summary_and_run_automation)
mock_generate_summary_only.assert_called_once_with(group.id)
- @patch("sentry.tasks.autofix.generate_issue_summary_only.delay")
+ @patch("sentry.tasks.seer.autofix.generate_issue_summary_only.delay")
@with_feature({"organizations:gen-ai-features": True})
def test_triage_signals_event_count_less_than_10_with_cache(
self, mock_generate_summary_only, mock_seat_based_tier
@@ -3130,7 +3130,7 @@ def test_triage_signals_event_count_less_than_10_with_cache(
"sentry.seer.autofix.utils.has_project_connected_repos",
return_value=True,
)
- @patch("sentry.tasks.autofix.run_automation_only_task.delay")
+ @patch("sentry.tasks.seer.autofix.run_automation_only_task.delay")
@with_feature({"organizations:gen-ai-features": True})
def test_triage_signals_event_count_gte_10_with_cache(
self, mock_run_automation, mock_has_repos, mock_seat_based_tier
@@ -3177,7 +3177,7 @@ def mock_buffer_get(model, columns, filters):
"sentry.seer.autofix.utils.has_project_connected_repos",
return_value=True,
)
- @patch("sentry.tasks.autofix.generate_summary_and_run_automation.delay")
+ @patch("sentry.tasks.seer.autofix.generate_summary_and_run_automation.delay")
@with_feature({"organizations:gen-ai-features": True})
def test_triage_signals_event_count_gte_10_no_cache(
self,
@@ -3223,7 +3223,7 @@ def mock_buffer_get(model, columns, filters):
"sentry.seer.autofix.utils.has_project_connected_repos",
return_value=False,
)
- @patch("sentry.tasks.autofix.generate_summary_and_run_automation.delay")
+ @patch("sentry.tasks.seer.autofix.generate_summary_and_run_automation.delay")
@with_feature({"organizations:gen-ai-features": True})
def test_triage_signals_event_count_gte_10_skips_without_connected_repos(
self,
@@ -3262,7 +3262,7 @@ def mock_buffer_get(model, columns, filters):
# Should not call automation since no connected repos
mock_generate_summary_and_run_automation.assert_not_called()
- @patch("sentry.tasks.autofix.run_automation_only_task.delay")
+ @patch("sentry.tasks.seer.autofix.run_automation_only_task.delay")
@with_feature({"organizations:gen-ai-features": True})
def test_triage_signals_event_count_gte_10_skips_with_seer_last_triggered(
self, mock_run_automation, mock_seat_based_tier
@@ -3306,7 +3306,7 @@ def mock_buffer_get(model, columns, filters):
# Should not call automation since seer_autofix_last_triggered is set
mock_run_automation.assert_not_called()
- @patch("sentry.tasks.autofix.run_automation_only_task.delay")
+ @patch("sentry.tasks.seer.autofix.run_automation_only_task.delay")
@with_feature({"organizations:gen-ai-features": True})
def test_triage_signals_event_count_gte_10_skips_with_existing_fixability_score(
self, mock_run_automation, mock_seat_based_tier
@@ -3351,8 +3351,8 @@ def mock_buffer_get(model, columns, filters):
# Should not call automation since seer_fixability_score is below MEDIUM threshold
mock_run_automation.assert_not_called()
- @patch("sentry.tasks.autofix.generate_summary_and_run_automation.delay")
- @patch("sentry.tasks.autofix.run_automation_only_task.delay")
+ @patch("sentry.tasks.seer.autofix.generate_summary_and_run_automation.delay")
+ @patch("sentry.tasks.seer.autofix.run_automation_only_task.delay")
@with_feature({"organizations:gen-ai-features": True})
def test_triage_signals_skips_automation_for_old_issues(
self,
From 3974941f65e499f7c664dfa6f7a628e43c535f70 Mon Sep 17 00:00:00 2001
From: George Gritsouk <989898+gggritso@users.noreply.github.com>
Date: Tue, 24 Mar 2026 14:21:02 -0400
Subject: [PATCH 17/38] fix(insights): Show <0.0001 for very small numeric
values instead of 0 (#111228)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When a numeric value is very small (less than 0.0001), the field
renderer and dashboard widgets were silently rounding it to 0 due to
fractional digit capping. This was misleading — e.g. the Jobs widget
could show "0 failed jobs" when the actual rate was tiny but nonzero.
**e.g.,**
Values below the minimum representable threshold now display as
`<0.0001` instead of `0`. A tooltip on hover shows the locale-formatted
actual value so users can still see the precise number if needed. This
is the pattern we also follow for other value types, like rates.
**e.g.,**
Longer term, when we come back and talk about how we want to format
numbers across the product, we'll come back to this decision. There's a
decent chance we'll be using scientific notation, for example.
Fixes DAIN-1378
---------
Co-authored-by: Claude
---
static/app/utils/discover/fieldRenderers.tsx | 42 +++++++++++++------
.../widgetCard/visualizationWidget.tsx | 18 ++++++--
.../dashboards/widgets/common/settings.tsx | 1 +
.../formatters/formatBreakdownLegendValue.tsx | 33 +++++++++++++++
.../formatters/formatTooltipValue.spec.tsx | 4 +-
.../formatters/formatTooltipValue.tsx | 13 +++++-
.../timeSeriesWidgetVisualization.tsx | 4 +-
7 files changed, 95 insertions(+), 20 deletions(-)
create mode 100644 static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatBreakdownLegendValue.tsx
diff --git a/static/app/utils/discover/fieldRenderers.tsx b/static/app/utils/discover/fieldRenderers.tsx
index dbc36c95700fc4..ab05167b223f9b 100644
--- a/static/app/utils/discover/fieldRenderers.tsx
+++ b/static/app/utils/discover/fieldRenderers.tsx
@@ -63,7 +63,11 @@ import {
findLinkedDashboardForField,
getLinkedDashboardUrl,
} from 'sentry/views/dashboards/utils/getLinkedDashboardUrl';
-import {NUMBER_MAX_FRACTION_DIGITS} from 'sentry/views/dashboards/widgets/common/settings';
+import {
+ NUMBER_MAX_FRACTION_DIGITS,
+ NUMBER_MIN_VALUE,
+} from 'sentry/views/dashboards/widgets/common/settings';
+import {formatTooltipValue} from 'sentry/views/dashboards/widgets/timeSeriesWidget/formatters/formatTooltipValue';
import {QuickContextHoverWrapper} from 'sentry/views/discover/table/quickContext/quickContextWrapper';
import {ContextType} from 'sentry/views/discover/table/quickContext/utils';
import type {TraceItemDetailsMeta} from 'sentry/views/explore/hooks/useTraceItemDetails';
@@ -302,18 +306,30 @@ export const FIELD_FORMATTERS: FieldFormatters = {
},
number: {
isSortable: true,
- renderFunc: (field, data) => (
-
- {typeof data[field] === 'number'
- ? formatFloat(data[field], NUMBER_MAX_FRACTION_DIGITS).toLocaleString(
- undefined,
- {
- maximumFractionDigits: NUMBER_MAX_FRACTION_DIGITS,
- }
- )
- : emptyValue}
-
- ),
+ renderFunc: (field, data) => {
+ if (typeof data[field] !== 'number') {
+ return {emptyValue};
+ }
+ if (data[field] > 0 && data[field] < NUMBER_MIN_VALUE) {
+ return (
+
+
+ {`<${NUMBER_MIN_VALUE}`}
+
+
+ );
+ }
+ return (
+
+ {formatFloat(data[field], NUMBER_MAX_FRACTION_DIGITS).toLocaleString(
+ undefined,
+ {
+ maximumFractionDigits: NUMBER_MAX_FRACTION_DIGITS,
+ }
+ )}
+
+ );
+ },
},
percentage: {
isSortable: true,
diff --git a/static/app/views/dashboards/widgetCard/visualizationWidget.tsx b/static/app/views/dashboards/widgetCard/visualizationWidget.tsx
index 8f7782deae18c6..d43e2cd2fcec6b 100644
--- a/static/app/views/dashboards/widgetCard/visualizationWidget.tsx
+++ b/static/app/views/dashboards/widgetCard/visualizationWidget.tsx
@@ -31,14 +31,17 @@ import {
import {getChartType} from 'sentry/views/dashboards/utils/getWidgetExploreUrl';
import {matchTimeSeriesToTableRowValue} from 'sentry/views/dashboards/widgetCard/matchTimeSeriesToTableRowValue';
import {transformWidgetSeriesToTimeSeries} from 'sentry/views/dashboards/widgetCard/transformWidgetSeriesToTimeSeries';
-import {MISSING_DATA_MESSAGE} from 'sentry/views/dashboards/widgets/common/settings';
+import {
+ MISSING_DATA_MESSAGE,
+ NUMBER_MIN_VALUE,
+} from 'sentry/views/dashboards/widgets/common/settings';
import type {
LegendSelection,
TabularColumn,
TimeSeries,
TimeSeriesGroupBy,
} from 'sentry/views/dashboards/widgets/common/types';
-import {formatTooltipValue} from 'sentry/views/dashboards/widgets/timeSeriesWidget/formatters/formatTooltipValue';
+import {formatBreakdownLegendValue} from 'sentry/views/dashboards/widgets/timeSeriesWidget/formatters/formatBreakdownLegendValue';
import {createPlottableFromTimeSeries} from 'sentry/views/dashboards/widgets/timeSeriesWidget/plottables/createPlottableFromTimeSeries';
import type {Plottable} from 'sentry/views/dashboards/widgets/timeSeriesWidget/plottables/plottable';
import {Thresholds} from 'sentry/views/dashboards/widgets/timeSeriesWidget/plottables/thresholds';
@@ -359,7 +362,16 @@ function VisualizationWidgetContent({
{labelContent}
- {value === null ? '—' : formatTooltipValue(value, dataType, dataUnit)}
+ {dataType === 'number' &&
+ value !== null &&
+ value > 0 &&
+ value < NUMBER_MIN_VALUE ? (
+
+ {formatBreakdownLegendValue(value, dataType, dataUnit)}
+
+ ) : (
+ formatBreakdownLegendValue(value, dataType, dataUnit)
+ )}
);
diff --git a/static/app/views/dashboards/widgets/common/settings.tsx b/static/app/views/dashboards/widgets/common/settings.tsx
index 1a647c475a2142..00d749e2e9e3d6 100644
--- a/static/app/views/dashboards/widgets/common/settings.tsx
+++ b/static/app/views/dashboards/widgets/common/settings.tsx
@@ -28,6 +28,7 @@ export const NON_FINITE_NUMBER_MESSAGE = t('Value is not a finite number.');
// Currently we lose precision for actual number fields because we
// can't distinguish them from percentage-like fields that need capping.
export const NUMBER_MAX_FRACTION_DIGITS = 4;
+export const NUMBER_MIN_VALUE = 10 ** -NUMBER_MAX_FRACTION_DIGITS;
export const ALLOWED_CELL_ACTIONS = [
Actions.OPEN_INTERNAL_LINK,
diff --git a/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatBreakdownLegendValue.tsx b/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatBreakdownLegendValue.tsx
new file mode 100644
index 00000000000000..6a7aeddd73e29f
--- /dev/null
+++ b/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatBreakdownLegendValue.tsx
@@ -0,0 +1,33 @@
+import {ECHARTS_MISSING_DATA_VALUE} from 'sentry/utils/timeSeries/timeSeriesItemToEChartsDataPoint';
+import {NUMBER_MIN_VALUE} from 'sentry/views/dashboards/widgets/common/settings';
+
+import {formatTooltipValue} from './formatTooltipValue';
+
+/**
+ * Format a value for the breakdown legend table under a chart.
+ *
+ * Similar to formatTooltipValue, but purpose-built for the legend context.
+ * For small "number" values, shows a threshold indicator (e.g. "<0.0001")
+ * rather than the full precision shown in chart tooltips.
+ * Also handles null values, which are displayed as an em dash.
+ */
+export function formatBreakdownLegendValue(
+ value: number | null | typeof ECHARTS_MISSING_DATA_VALUE,
+ type: string,
+ unit?: string
+): string {
+ if (value === null) {
+ return '—';
+ }
+
+ if (
+ type === 'number' &&
+ typeof value === 'number' &&
+ value > 0 &&
+ value < NUMBER_MIN_VALUE
+ ) {
+ return `<${NUMBER_MIN_VALUE}`;
+ }
+
+ return formatTooltipValue(value, type, unit);
+}
diff --git a/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTooltipValue.spec.tsx b/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTooltipValue.spec.tsx
index 8fe367f7bbc818..4c7ec96079cec0 100644
--- a/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTooltipValue.spec.tsx
+++ b/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTooltipValue.spec.tsx
@@ -16,8 +16,8 @@ describe('formatTooltipValue', () => {
describe('number', () => {
it.each([
- [0.000033452, '0'],
- [0.00003, '0'],
+ [0.000033452, '0.00003345'],
+ [0.00003, '0.00003'],
[0.001234, '0.0012'],
[17.1238, '17.1238'],
[170, '170'],
diff --git a/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTooltipValue.tsx b/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTooltipValue.tsx
index 1fb84d32eb3cce..3a5bfe55dc8225 100644
--- a/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTooltipValue.tsx
+++ b/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTooltipValue.tsx
@@ -12,7 +12,10 @@ import {formatPercentage} from 'sentry/utils/number/formatPercentage';
import {ECHARTS_MISSING_DATA_VALUE} from 'sentry/utils/timeSeries/timeSeriesItemToEChartsDataPoint';
import {convertDuration} from 'sentry/utils/unitConversion/convertDuration';
import {convertSize} from 'sentry/utils/unitConversion/convertSize';
-import {NUMBER_MAX_FRACTION_DIGITS} from 'sentry/views/dashboards/widgets/common/settings';
+import {
+ NUMBER_MAX_FRACTION_DIGITS,
+ NUMBER_MIN_VALUE,
+} from 'sentry/views/dashboards/widgets/common/settings';
import {
isADurationUnit,
isASizeUnit,
@@ -36,7 +39,15 @@ export function formatTooltipValue(
switch (type) {
case 'integer':
+ return value.toLocaleString(undefined, {
+ maximumFractionDigits: NUMBER_MAX_FRACTION_DIGITS,
+ });
case 'number':
+ if (value > 0 && value < NUMBER_MIN_VALUE) {
+ return value.toLocaleString(undefined, {
+ maximumSignificantDigits: NUMBER_MAX_FRACTION_DIGITS,
+ });
+ }
return value.toLocaleString(undefined, {
maximumFractionDigits: NUMBER_MAX_FRACTION_DIGITS,
});
diff --git a/static/app/views/dashboards/widgets/timeSeriesWidget/timeSeriesWidgetVisualization.tsx b/static/app/views/dashboards/widgets/timeSeriesWidget/timeSeriesWidgetVisualization.tsx
index 641842b3b3c3e8..7e3c2f4b8500f4 100644
--- a/static/app/views/dashboards/widgets/timeSeriesWidget/timeSeriesWidgetVisualization.tsx
+++ b/static/app/views/dashboards/widgets/timeSeriesWidget/timeSeriesWidgetVisualization.tsx
@@ -380,7 +380,9 @@ export function TimeSeriesWidgetVisualization(props: TimeSeriesWidgetVisualizati
const fieldType = correspondingPlottable?.dataType ?? FALLBACK_TYPE;
- return formatTooltipValue(value, fieldType, unitForType[fieldType] ?? undefined);
+ return escape(
+ formatTooltipValue(value, fieldType, unitForType[fieldType] ?? undefined)
+ );
},
truncate: false,
utc: utc ?? false,
From 92ffbcf542661cc19e606b7f90228c73b4e02a18 Mon Sep 17 00:00:00 2001
From: Kev <6111995+k-fish@users.noreply.github.com>
Date: Tue, 24 Mar 2026 14:23:57 -0400
Subject: [PATCH 18/38] feat(tracemetrics): Add trace metric bytes DataCategory
to stats page (#111431)
Add TRACE_METRIC_BYTE to DataCategory enums, DATA_CATEGORY_INFO with
bytes formatting, and gate visibility behind canUseMetricsStatsBytesUI
---
static/app/constants/index.spec.tsx | 12 ++++++++++--
static/app/constants/index.tsx | 16 ++++++++++++++++
static/app/types/core.tsx | 2 ++
.../app/views/explore/metrics/metricsFlags.tsx | 7 +++++++
static/app/views/organizationStats/index.tsx | 8 +++++++-
static/app/views/organizationStats/utils.tsx | 9 ++++++---
6 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/static/app/constants/index.spec.tsx b/static/app/constants/index.spec.tsx
index 06e9a8de96409e..48e25a1040fff7 100644
--- a/static/app/constants/index.spec.tsx
+++ b/static/app/constants/index.spec.tsx
@@ -12,7 +12,11 @@ describe('DATA_CATEGORY_INFO', () => {
});
it('byte categories have correct formatting', () => {
- const byteCategories = [DataCategoryExact.ATTACHMENT, DataCategoryExact.LOG_BYTE];
+ const byteCategories = [
+ DataCategoryExact.ATTACHMENT,
+ DataCategoryExact.LOG_BYTE,
+ DataCategoryExact.TRACE_METRIC_BYTE,
+ ];
for (const category of byteCategories) {
const {formatting} = DATA_CATEGORY_INFO[category];
@@ -72,7 +76,11 @@ describe('DATA_CATEGORY_INFO', () => {
});
it('formatting unitType matches expected categories', () => {
- const bytesCategories = [DataCategoryExact.ATTACHMENT, DataCategoryExact.LOG_BYTE];
+ const bytesCategories = [
+ DataCategoryExact.ATTACHMENT,
+ DataCategoryExact.LOG_BYTE,
+ DataCategoryExact.TRACE_METRIC_BYTE,
+ ];
const durationHoursCategories = [
DataCategoryExact.PROFILE_DURATION,
DataCategoryExact.PROFILE_DURATION_UI,
diff --git a/static/app/constants/index.tsx b/static/app/constants/index.tsx
index cc07c2afe6a95f..583236a1bd4b99 100644
--- a/static/app/constants/index.tsx
+++ b/static/app/constants/index.tsx
@@ -645,6 +645,22 @@ export const DATA_CATEGORY_INFO = {
},
formatting: DEFAULT_COUNT_FORMATTING,
},
+ [DataCategoryExact.TRACE_METRIC_BYTE]: {
+ name: DataCategoryExact.TRACE_METRIC_BYTE,
+ plural: DataCategory.TRACE_METRIC_BYTE,
+ singular: 'traceMetricByte',
+ displayName: 'metric byte',
+ titleName: t('Metrics (Bytes)'),
+ productName: t('Metrics'),
+ uid: 37,
+ isBilledCategory: false,
+ statsInfo: {
+ ...DEFAULT_STATS_INFO,
+ showExternalStats: true,
+ yAxisMinInterval: 1 * KILOBYTE,
+ },
+ formatting: BYTES_FORMATTING,
+ },
[DataCategoryExact.SEER_USER]: {
name: DataCategoryExact.SEER_USER,
plural: DataCategory.SEER_USER,
diff --git a/static/app/types/core.tsx b/static/app/types/core.tsx
index 9c5ae3990cd33c..a2317839f2de0b 100644
--- a/static/app/types/core.tsx
+++ b/static/app/types/core.tsx
@@ -98,6 +98,7 @@ export enum DataCategory {
SEER_USER = 'seerUsers',
USER_REPORT_V2 = 'feedback',
TRACE_METRICS = 'traceMetrics',
+ TRACE_METRIC_BYTE = 'traceMetricBytes',
SIZE_ANALYSIS = 'sizeAnalyses',
INSTALLABLE_BUILD = 'installableBuilds',
}
@@ -132,6 +133,7 @@ export enum DataCategoryExact {
SEER_USER = 'seer_user',
USER_REPORT_V2 = 'feedback',
TRACE_METRIC = 'trace_metric',
+ TRACE_METRIC_BYTE = 'trace_metric_byte',
SIZE_ANALYSIS = 'size_analysis',
INSTALLABLE_BUILD = 'installable_build',
}
diff --git a/static/app/views/explore/metrics/metricsFlags.tsx b/static/app/views/explore/metrics/metricsFlags.tsx
index dbba20d77e3413..17052c30b48385 100644
--- a/static/app/views/explore/metrics/metricsFlags.tsx
+++ b/static/app/views/explore/metrics/metricsFlags.tsx
@@ -34,3 +34,10 @@ export const canUseMetricsUIRefresh = (organization: Organization) => {
organization.features.includes('tracemetrics-ui-refresh')
);
};
+
+export const canUseMetricsStatsBytesUI = (organization: Organization) => {
+ return (
+ canUseMetricsUI(organization) &&
+ organization.features.includes('tracemetrics-stats-bytes-ui')
+ );
+};
diff --git a/static/app/views/organizationStats/index.tsx b/static/app/views/organizationStats/index.tsx
index 1e3a05ae68adf9..44c190e5091d3b 100644
--- a/static/app/views/organizationStats/index.tsx
+++ b/static/app/views/organizationStats/index.tsx
@@ -31,7 +31,10 @@ import {decodeScalar} from 'sentry/utils/queryString';
import {useLocation} from 'sentry/utils/useLocation';
import {useNavigate, type ReactRouter3Navigate} from 'sentry/utils/useNavigate';
import {useOrganization} from 'sentry/utils/useOrganization';
-import {canUseMetricsStatsUI} from 'sentry/views/explore/metrics/metricsFlags';
+import {
+ canUseMetricsStatsBytesUI,
+ canUseMetricsStatsUI,
+} from 'sentry/views/explore/metrics/metricsFlags';
import {StatsHeader as HeaderTabs} from 'sentry/views/organizationStats/header';
import {getPerformanceBaseUrl} from 'sentry/views/performance/utils';
import {makeProjectsPathname} from 'sentry/views/projects/pathname';
@@ -277,6 +280,9 @@ export class OrganizationStatsInner extends Component {
if ([DataCategory.TRACE_METRICS].includes(opt.value)) {
return canUseMetricsStatsUI(organization);
}
+ if ([DataCategory.TRACE_METRIC_BYTE].includes(opt.value)) {
+ return canUseMetricsStatsBytesUI(organization);
+ }
if (
[DataCategory.PROFILE_DURATION, DataCategory.PROFILE_DURATION_UI].includes(
opt.value
diff --git a/static/app/views/organizationStats/utils.tsx b/static/app/views/organizationStats/utils.tsx
index 33957e1ec1ff99..21d274767bb4d2 100644
--- a/static/app/views/organizationStats/utils.tsx
+++ b/static/app/views/organizationStats/utils.tsx
@@ -34,7 +34,8 @@ export function formatUsageWithUnits(
): string {
if (
dataCategory === DATA_CATEGORY_INFO.attachment.plural ||
- dataCategory === DATA_CATEGORY_INFO.log_byte.plural
+ dataCategory === DATA_CATEGORY_INFO.log_byte.plural ||
+ dataCategory === DATA_CATEGORY_INFO.trace_metric_byte.plural
) {
if (options.useUnitScaling) {
return formatBytesBase10(usageQuantity);
@@ -70,10 +71,12 @@ export function getFormatUsageOptions(dataCategory: DataCategory): FormatOptions
return {
isAbbreviated:
dataCategory !== DATA_CATEGORY_INFO.attachment.plural &&
- dataCategory !== DATA_CATEGORY_INFO.log_byte.plural,
+ dataCategory !== DATA_CATEGORY_INFO.log_byte.plural &&
+ dataCategory !== DATA_CATEGORY_INFO.trace_metric_byte.plural,
useUnitScaling:
dataCategory === DATA_CATEGORY_INFO.attachment.plural ||
- dataCategory === DATA_CATEGORY_INFO.log_byte.plural,
+ dataCategory === DATA_CATEGORY_INFO.log_byte.plural ||
+ dataCategory === DATA_CATEGORY_INFO.trace_metric_byte.plural,
};
}
From 50a660a93048bc04531f987f157e68f21b0e5bb6 Mon Sep 17 00:00:00 2001
From: edwardgou-sentry <83961295+edwardgou-sentry@users.noreply.github.com>
Date: Tue, 24 Mar 2026 14:38:15 -0400
Subject: [PATCH 19/38] feat(dashboards): Adds more description context to
artifact schema (#111417)
Adds more descriptions to artifact schema for dashboard generation
---
.../dashboards/models/generate_dashboard_artifact.py | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/sentry/dashboards/models/generate_dashboard_artifact.py b/src/sentry/dashboards/models/generate_dashboard_artifact.py
index bc645a3c386d08..3852c5323537fa 100644
--- a/src/sentry/dashboards/models/generate_dashboard_artifact.py
+++ b/src/sentry/dashboards/models/generate_dashboard_artifact.py
@@ -72,6 +72,8 @@ def check_blocklist(cls, v: str) -> str:
class GeneratedWidgetLayout(BaseModel):
+ """Layout position and size on a 6-column grid. Widget widths in each row should sum to 6 to fill the grid completely."""
+
x: int = Field(
default=0,
description=f"Column position (0-{GRID_WIDTH - 1}). x + w must not exceed {GRID_WIDTH}.",
@@ -115,12 +117,17 @@ def fit_within_grid(cls, w: int, values: dict[str, Any]) -> int:
class GeneratedWidget(BaseModel):
+ """A single dashboard widget. Default sizes by display type: big_number 2w x 1h (3 per row), line/area/bar/stacked_area/top_n 3w x 2h (2 per row), table 6w x 2h (full row)."""
+
title: str = Field(..., max_length=255) # Matches serializer
description: str = Field(
..., max_length=255
) # Length matches serializer, required field for generation
display_type: DisplayType
- widget_type: WidgetType
+ widget_type: WidgetType = Field(
+ ...,
+ description="Dataset to query. Use 'spans' as the default — it covers most use cases. Use 'error-events' for error-specific data, 'issue' for issue tracking, 'logs' for log data, 'tracemetrics' for trace metrics.",
+ )
queries: list[GeneratedWidgetQuery]
layout: GeneratedWidgetLayout
limit: int | None = Field(default=None, le=10, ge=1)
@@ -128,5 +135,7 @@ class GeneratedWidget(BaseModel):
class GeneratedDashboard(BaseModel):
+ """A complete dashboard definition on a 6-column grid. Widget widths per row must sum to 6. This is the sole output artifact."""
+
title: str = Field(..., max_length=255) # Matches serializer
widgets: list[GeneratedWidget] = Field(..., max_items=Dashboard.MAX_WIDGETS)
From eb889f93d6b07c714a423db1619a7f8bc4edcd2b Mon Sep 17 00:00:00 2001
From: Malachi Willey
Date: Tue, 24 Mar 2026 11:39:57 -0700
Subject: [PATCH 20/38] feat(aci): Add issue preview to the metric monitor form
(#111420)
- Adds an issue preview to the metric monitor form
- Refactors the issue preview component to use SimpleTable and thus look
more similar to the actual issue stream
- Add support for sending "assignee" to the issue preview
- Add a reusable issue preview section wrapper since should look the
same in most detector forms
---
.../forms/common/detectorIssuePreview.tsx | 110 ++++++------------
.../forms/common/issuePreviewSection.tsx | 18 +++
.../components/forms/common/ownerToActor.tsx | 15 +++
.../components/forms/metric/metric.spec.tsx | 76 +++++++++++-
.../components/forms/metric/metric.tsx | 2 +
.../forms/metric/metricIssuePreview.tsx | 96 +++++++++++++++
.../forms/mobileBuild/previewSection.tsx | 13 ++-
7 files changed, 252 insertions(+), 78 deletions(-)
create mode 100644 static/app/views/detectors/components/forms/common/issuePreviewSection.tsx
create mode 100644 static/app/views/detectors/components/forms/common/ownerToActor.tsx
create mode 100644 static/app/views/detectors/components/forms/metric/metricIssuePreview.tsx
diff --git a/static/app/views/detectors/components/forms/common/detectorIssuePreview.tsx b/static/app/views/detectors/components/forms/common/detectorIssuePreview.tsx
index 70cdb7def3956c..2ac92d5e510b24 100644
--- a/static/app/views/detectors/components/forms/common/detectorIssuePreview.tsx
+++ b/static/app/views/detectors/components/forms/common/detectorIssuePreview.tsx
@@ -1,19 +1,18 @@
-import {useTheme} from '@emotion/react';
-
-import {Flex, Grid} from '@sentry/scraps/layout';
+import {ActorAvatar} from '@sentry/scraps/avatar';
+import {Flex} from '@sentry/scraps/layout';
import {Text} from '@sentry/scraps/text';
-import {ErrorLevel} from 'sentry/components/events/errorLevel';
import {ShortId} from 'sentry/components/group/inboxBadges/shortId';
import ProjectBadge from 'sentry/components/idBadge/projectBadge';
-import {Container} from 'sentry/components/workflowEngine/ui/container';
-import {Section} from 'sentry/components/workflowEngine/ui/section';
+import {SimpleTable} from 'sentry/components/tables/simpleTable';
import {t} from 'sentry/locale';
+import type {Actor} from 'sentry/types/core';
import type {AvatarProject} from 'sentry/types/project';
interface DetectorIssuePreviewProps {
issueTitle: string;
subtitle: string;
+ assignee?: Actor;
project?: AvatarProject;
}
@@ -21,77 +20,44 @@ export function DetectorIssuePreview({
issueTitle,
project,
subtitle,
+ assignee,
}: DetectorIssuePreviewProps) {
- const theme = useTheme();
const projectSlug = project?.slug ?? 'project';
const shortId = `${projectSlug.toUpperCase()}-D3M0`;
- return (
-
-
-
-
-
- {t('Issue')}
-
-
-
- {t('Last Seen')}
-
-
- {t('Age')}
-
-
- {t('Events')}
-
-
- {t('Users')}
-
-
- {t('Assignee')}
-
-
-
- {issueTitle}
-
-
- {subtitle}
-
-
- {project && }
-
-
-
-
+ return (
+
+
+ {t('Issue')}
+ {t('Last Seen')}
+ {t('Age')}
+ {t('Events')}
+ {t('Users')}
+ {t('Assignee')}
+
+
+
+
+
+ {issueTitle}
+
+ {subtitle}
+
+ {project && }
+
+
+
- 4hr ago
- 2min
- 1
- 1.2k
-
-
-
+
+ 2min ago
+ 4h
+ 1.2k
+ 620
+
+ {assignee && }
+
+
+
);
}
diff --git a/static/app/views/detectors/components/forms/common/issuePreviewSection.tsx b/static/app/views/detectors/components/forms/common/issuePreviewSection.tsx
new file mode 100644
index 00000000000000..eb80448b54222f
--- /dev/null
+++ b/static/app/views/detectors/components/forms/common/issuePreviewSection.tsx
@@ -0,0 +1,18 @@
+import {Container} from 'sentry/components/workflowEngine/ui/container';
+import {Section} from 'sentry/components/workflowEngine/ui/section';
+import {t} from 'sentry/locale';
+
+export function IssuePreviewSection({children}: {children: React.ReactNode}) {
+ return (
+
+
+
+ );
+}
diff --git a/static/app/views/detectors/components/forms/common/ownerToActor.tsx b/static/app/views/detectors/components/forms/common/ownerToActor.tsx
new file mode 100644
index 00000000000000..b5b5d5ce1b48a2
--- /dev/null
+++ b/static/app/views/detectors/components/forms/common/ownerToActor.tsx
@@ -0,0 +1,15 @@
+import type {Actor} from 'sentry/types/core';
+
+/**
+ * Converts an owner string (e.g. "user:123" or "team:456") to an Actor object.
+ */
+export function ownerToActor(owner: string | undefined): Actor | undefined {
+ if (!owner) {
+ return undefined;
+ }
+ const [type, id] = owner.split(':');
+ if (!id || (type !== 'team' && type !== 'user')) {
+ return undefined;
+ }
+ return {type, id, name: ''};
+}
diff --git a/static/app/views/detectors/components/forms/metric/metric.spec.tsx b/static/app/views/detectors/components/forms/metric/metric.spec.tsx
index 10feb37d02b5e2..5764a7eaade4d1 100644
--- a/static/app/views/detectors/components/forms/metric/metric.spec.tsx
+++ b/static/app/views/detectors/components/forms/metric/metric.spec.tsx
@@ -1,9 +1,11 @@
import {OrganizationFixture} from 'sentry-fixture/organization';
import {ProjectFixture} from 'sentry-fixture/project';
+import {UserFixture} from 'sentry-fixture/user';
-import {render, screen, within} from 'sentry-test/reactTestingLibrary';
+import {render, screen, userEvent, within} from 'sentry-test/reactTestingLibrary';
import {selectEvent} from 'sentry-test/selectEvent';
+import {MemberListStore} from 'sentry/stores/memberListStore';
import {OrganizationStore} from 'sentry/stores/organizationStore';
import {DetectorFormProvider} from 'sentry/views/detectors/components/forms/context';
import {NewMetricDetectorForm} from 'sentry/views/detectors/components/forms/metric/metric';
@@ -18,6 +20,8 @@ describe('NewMetricDetectorForm', () => {
MockApiClient.clearMockResponses();
OrganizationStore.reset();
OrganizationStore.onUpdate(organization);
+ MemberListStore.init();
+ MemberListStore.loadInitialData([UserFixture()]);
MockApiClient.addMockResponse({
url: '/organizations/org-slug/events-stats/',
@@ -63,6 +67,76 @@ describe('NewMetricDetectorForm', () => {
url: '/organizations/org-slug/projects/',
body: [project],
});
+ MockApiClient.addMockResponse({
+ url: '/organizations/org-slug/user-teams/',
+ body: [],
+ });
+ });
+
+ it('shows default issue preview and updates subtitle when threshold changes', async () => {
+ render(
+
+
+ ,
+ {organization}
+ );
+
+ // Default title and subtitle
+ expect(await screen.findByText('Monitor title')).toBeInTheDocument();
+ expect(
+ screen.getByText('Critical: Number of errors above ... in 1 hour')
+ ).toBeInTheDocument();
+
+ // Change the monitor name and verify it updates the preview
+ await userEvent.click(screen.getByTestId('editable-text-label'));
+ await userEvent.clear(screen.getByRole('textbox', {name: 'Monitor Name'}));
+ await userEvent.type(
+ screen.getByRole('textbox', {name: 'Monitor Name'}),
+ 'My Custom Monitor'
+ );
+ await userEvent.keyboard('{Enter}');
+ const preview = screen.getByTestId('issue-preview-section');
+ expect(within(preview).getByText('My Custom Monitor')).toBeInTheDocument();
+
+ // Change the high threshold
+ await userEvent.type(screen.getByRole('spinbutton', {name: 'High threshold'}), '100');
+
+ expect(
+ within(preview).getByText('Critical: Number of errors above 100 in 1 hour')
+ ).toBeInTheDocument();
+
+ // Switch to percent change detection type — threshold value carries over
+ await userEvent.click(screen.getByRole('radio', {name: /Change/i}));
+
+ expect(
+ within(preview).getByText(
+ 'Critical: Number of errors higher by 100% compared to past 1 hour'
+ )
+ ).toBeInTheDocument();
+
+ // Clear and set a new percent threshold
+ await userEvent.clear(screen.getByRole('spinbutton', {name: 'High threshold'}));
+ await userEvent.type(screen.getByRole('spinbutton', {name: 'High threshold'}), '50');
+
+ expect(
+ within(preview).getByText(
+ 'Critical: Number of errors higher by 50% compared to past 1 hour'
+ )
+ ).toBeInTheDocument();
+
+ // Switch to dynamic (anomaly) detection type
+ await userEvent.click(screen.getByRole('radio', {name: /Dynamic/i}));
+
+ expect(
+ within(preview).getByText('Detected an anomaly in the query for Number of errors')
+ ).toBeInTheDocument();
+
+ // Change the assignee and verify it shows in the preview
+ await selectEvent.select(
+ screen.getByRole('textbox', {name: 'Default assignee'}),
+ 'Foo Bar'
+ );
+ expect(within(preview).getByText('FB')).toBeInTheDocument();
});
it('removes is filters when switching away from the errors dataset', async () => {
diff --git a/static/app/views/detectors/components/forms/metric/metric.tsx b/static/app/views/detectors/components/forms/metric/metric.tsx
index 421119bcb21fb6..df95a50358d42b 100644
--- a/static/app/views/detectors/components/forms/metric/metric.tsx
+++ b/static/app/views/detectors/components/forms/metric/metric.tsx
@@ -44,6 +44,7 @@ import {
metricSavedDetectorToFormData,
useMetricDetectorFormField,
} from 'sentry/views/detectors/components/forms/metric/metricFormData';
+import {MetricIssuePreview} from 'sentry/views/detectors/components/forms/metric/metricIssuePreview';
import {MetricDetectorPreviewChart} from 'sentry/views/detectors/components/forms/metric/previewChart';
import {DetectorQueryFilterBuilder} from 'sentry/views/detectors/components/forms/metric/queryFilterBuilder';
import {ResolveSection} from 'sentry/views/detectors/components/forms/metric/resolveSection';
@@ -77,6 +78,7 @@ function MetricDetectorForm() {
+
);
diff --git a/static/app/views/detectors/components/forms/metric/metricIssuePreview.tsx b/static/app/views/detectors/components/forms/metric/metricIssuePreview.tsx
new file mode 100644
index 00000000000000..c50799b6113bde
--- /dev/null
+++ b/static/app/views/detectors/components/forms/metric/metricIssuePreview.tsx
@@ -0,0 +1,96 @@
+import {t} from 'sentry/locale';
+import {DataConditionType} from 'sentry/types/workflowEngine/dataConditions';
+import {getDuration} from 'sentry/utils/duration/getDuration';
+import {DetectorIssuePreview} from 'sentry/views/detectors/components/forms/common/detectorIssuePreview';
+import {IssuePreviewSection} from 'sentry/views/detectors/components/forms/common/issuePreviewSection';
+import {ownerToActor} from 'sentry/views/detectors/components/forms/common/ownerToActor';
+import {useDetectorFormContext} from 'sentry/views/detectors/components/forms/context';
+import {
+ METRIC_DETECTOR_FORM_FIELDS,
+ useMetricDetectorFormField,
+} from 'sentry/views/detectors/components/forms/metric/metricFormData';
+import {getDatasetConfig} from 'sentry/views/detectors/datasetConfig/getDatasetConfig';
+import {getMetricDetectorSuffix} from 'sentry/views/detectors/utils/metricDetectorSuffix';
+
+function useMetricIssuePreviewSubtitle() {
+ const detectionType = useMetricDetectorFormField(
+ METRIC_DETECTOR_FORM_FIELDS.detectionType
+ );
+ const aggregate = useMetricDetectorFormField(
+ METRIC_DETECTOR_FORM_FIELDS.aggregateFunction
+ );
+ const dataset = useMetricDetectorFormField(METRIC_DETECTOR_FORM_FIELDS.dataset);
+ const interval = useMetricDetectorFormField(METRIC_DETECTOR_FORM_FIELDS.interval);
+ const highThreshold = useMetricDetectorFormField(
+ METRIC_DETECTOR_FORM_FIELDS.highThreshold
+ );
+ const conditionType = useMetricDetectorFormField(
+ METRIC_DETECTOR_FORM_FIELDS.conditionType
+ );
+ const conditionComparisonAgo = useMetricDetectorFormField(
+ METRIC_DETECTOR_FORM_FIELDS.conditionComparisonAgo
+ );
+
+ const datasetConfig = getDatasetConfig(dataset);
+ const formattedAggregate =
+ datasetConfig.formatAggregateForTitle?.(aggregate) ?? aggregate;
+ const intervalLabel = getDuration(interval);
+ const thresholdLabel = highThreshold || t('...');
+
+ switch (detectionType) {
+ case 'static': {
+ const direction =
+ conditionType === DataConditionType.LESS ? t('below') : t('above');
+ const suffix = getMetricDetectorSuffix('static', aggregate);
+ return t(
+ 'Critical: %(aggregate)s %(direction)s %(threshold)s%(suffix)s in %(interval)s',
+ {
+ aggregate: formattedAggregate,
+ direction,
+ threshold: thresholdLabel,
+ suffix,
+ interval: intervalLabel,
+ }
+ );
+ }
+ case 'percent': {
+ const direction =
+ conditionType === DataConditionType.LESS ? t('lower') : t('higher');
+ return t(
+ 'Critical: %(aggregate)s %(direction)s by %(threshold)s%% compared to past %(interval)s',
+ {
+ aggregate: formattedAggregate,
+ direction,
+ threshold: thresholdLabel,
+ interval: getDuration(conditionComparisonAgo ?? interval),
+ }
+ );
+ }
+ case 'dynamic': {
+ return t('Detected an anomaly in the query for %(aggregate)s', {
+ aggregate: formattedAggregate,
+ });
+ }
+ default:
+ return t('Critical issue condition met');
+ }
+}
+
+export function MetricIssuePreview() {
+ const name = useMetricDetectorFormField(METRIC_DETECTOR_FORM_FIELDS.name);
+ const owner = useMetricDetectorFormField(METRIC_DETECTOR_FORM_FIELDS.owner);
+ const subtitle = useMetricIssuePreviewSubtitle();
+ const assignee = ownerToActor(owner);
+ const {project} = useDetectorFormContext();
+
+ return (
+
+
+
+ );
+}
diff --git a/static/app/views/detectors/components/forms/mobileBuild/previewSection.tsx b/static/app/views/detectors/components/forms/mobileBuild/previewSection.tsx
index ab812d7502b3c1..0d04f0eafcc6da 100644
--- a/static/app/views/detectors/components/forms/mobileBuild/previewSection.tsx
+++ b/static/app/views/detectors/components/forms/mobileBuild/previewSection.tsx
@@ -1,6 +1,7 @@
import {t} from 'sentry/locale';
import {useProjects} from 'sentry/utils/useProjects';
import {DetectorIssuePreview} from 'sentry/views/detectors/components/forms/common/detectorIssuePreview';
+import {IssuePreviewSection} from 'sentry/views/detectors/components/forms/common/issuePreviewSection';
import {
PREPROD_DETECTOR_FORM_FIELDS,
usePreprodDetectorFormField,
@@ -38,10 +39,12 @@ export function MobileBuildPreviewSection() {
const thresholdDisplay = highThreshold ? `${threshold} ${thresholdUnit}` : '\u2026';
return (
- %s Threshold', actualDisplay, thresholdDisplay)}
- />
+
+ %s Threshold', actualDisplay, thresholdDisplay)}
+ />
+
);
}
From 895ba610d3e202d206f03ff318ce00f518b5e170 Mon Sep 17 00:00:00 2001
From: Dominik Buszowiecki <44422760+DominikB2014@users.noreply.github.com>
Date: Tue, 24 Mar 2026 14:40:31 -0400
Subject: [PATCH 21/38] ref(dashboards): Widen GroupBy value type to include
number and boolean (#111397)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## Summary
- Widens the `GroupBy.value` type in the timeseries widget types to
accept `number` and `boolean` in addition to the existing `string | null
| Array<...>` types
- Prepares the frontend for a backend change that will return real typed
values from the `events-timeseries` endpoint instead of always
stringifying groupBy values
All existing consumers already handle these types safely —
`toPythonString` normalizes bools/numbers, formatters have null/array
guards, and no direct `===` string comparisons exist against
`groupBy.value`.
Fixes BROWSE-468
---------
Co-authored-by: Claude Opus 4.6
---
.../matchTimeSeriesToTableRowValue.spec.tsx | 15 +++++++++++++++
.../widgetCard/widgetCardContextMenu.tsx | 2 +-
.../formatters/formatCategoricalSeriesLabel.tsx | 2 +-
.../app/views/dashboards/widgets/common/types.tsx | 2 +-
.../formatters/formatTimeSeriesLabel.tsx | 4 ++--
.../components/charts/responseCodeCountChart.tsx | 9 +++++++--
6 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/static/app/views/dashboards/widgetCard/matchTimeSeriesToTableRowValue.spec.tsx b/static/app/views/dashboards/widgetCard/matchTimeSeriesToTableRowValue.spec.tsx
index a1940aa4ff8712..fd6f213f92122a 100644
--- a/static/app/views/dashboards/widgetCard/matchTimeSeriesToTableRowValue.spec.tsx
+++ b/static/app/views/dashboards/widgetCard/matchTimeSeriesToTableRowValue.spec.tsx
@@ -82,6 +82,21 @@ describe('matchTimeSeriesToTableRowValue', () => {
expect(result).toBe(50);
});
+ it('matches numeric table values to numeric groupBy values', () => {
+ const result = matchTimeSeriesToTableRowValue({
+ tableDataRows: [
+ {id: '1', 'http.response_status_code': 200, 'count()': 50},
+ {id: '2', 'http.response_status_code': 404, 'count()': 3},
+ ],
+ timeSeries: TimeSeriesFixture({
+ yAxis: 'count()',
+ groupBy: [{key: 'http.response_status_code', value: 200}],
+ }),
+ });
+
+ expect(result).toBe(50);
+ });
+
it('matches array groupBy values using Python str() format', () => {
const result = matchTimeSeriesToTableRowValue({
tableDataRows: [
diff --git a/static/app/views/dashboards/widgetCard/widgetCardContextMenu.tsx b/static/app/views/dashboards/widgetCard/widgetCardContextMenu.tsx
index 1ddf951eeda5b0..1e7e4b824db3d0 100644
--- a/static/app/views/dashboards/widgetCard/widgetCardContextMenu.tsx
+++ b/static/app/views/dashboards/widgetCard/widgetCardContextMenu.tsx
@@ -306,7 +306,7 @@ export function getMenuOptions(
const search = new MutableSearch(baseQuery);
for (const group of timeSeries.groupBy ?? []) {
if (group.value !== null && !Array.isArray(group.value)) {
- search.addFilterValue(group.key, group.value);
+ search.addFilterValue(group.key, String(group.value));
}
}
diff --git a/static/app/views/dashboards/widgets/categoricalSeriesWidget/formatters/formatCategoricalSeriesLabel.tsx b/static/app/views/dashboards/widgets/categoricalSeriesWidget/formatters/formatCategoricalSeriesLabel.tsx
index 980331beaf111d..0ef06c7ab2b4f1 100644
--- a/static/app/views/dashboards/widgets/categoricalSeriesWidget/formatters/formatCategoricalSeriesLabel.tsx
+++ b/static/app/views/dashboards/widgets/categoricalSeriesWidget/formatters/formatCategoricalSeriesLabel.tsx
@@ -19,7 +19,7 @@ export function formatCategoricalSeriesLabel(series: CategoricalSeries): string
return t('(no value)');
}
- return groupBy.value;
+ return String(groupBy.value);
})
.join(',');
}
diff --git a/static/app/views/dashboards/widgets/common/types.tsx b/static/app/views/dashboards/widgets/common/types.tsx
index 4fa5264054a551..462144a3acbc83 100644
--- a/static/app/views/dashboards/widgets/common/types.tsx
+++ b/static/app/views/dashboards/widgets/common/types.tsx
@@ -78,7 +78,7 @@ type IncompleteReason = 'INCOMPLETE_BUCKET';
*/
type GroupBy = {
key: string;
- value: string | null | Array | Array;
+ value: string | number | boolean | null | Array | Array;
};
// Aliases - allows divergence later if unique cases arise
diff --git a/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTimeSeriesLabel.tsx b/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTimeSeriesLabel.tsx
index 60e3c26c6ed3e7..8897947291d8ed 100644
--- a/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTimeSeriesLabel.tsx
+++ b/static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTimeSeriesLabel.tsx
@@ -19,7 +19,7 @@ export function formatTimeSeriesLabel(timeSeries: TimeSeries): string {
return JSON.stringify(groupBy.value);
}
- if (groupBy.key === 'release' && groupBy.value) {
+ if (groupBy.key === 'release' && typeof groupBy.value === 'string') {
return formatVersion(groupBy.value);
}
@@ -27,7 +27,7 @@ export function formatTimeSeriesLabel(timeSeries: TimeSeries): string {
return t('(no value)');
}
- return groupBy.value;
+ return String(groupBy.value);
})
.join(',');
}
diff --git a/static/app/views/insights/http/components/charts/responseCodeCountChart.tsx b/static/app/views/insights/http/components/charts/responseCodeCountChart.tsx
index 57faa2e2496548..818175a29d663c 100644
--- a/static/app/views/insights/http/components/charts/responseCodeCountChart.tsx
+++ b/static/app/views/insights/http/components/charts/responseCodeCountChart.tsx
@@ -131,12 +131,17 @@ function getResponseCode(series: TimeSeries) {
return responseCodeGroupBy.value;
}
-function isNumeric(maybeNumber: string | number | null | undefined) {
- if (!maybeNumber) {
+function isNumeric(
+ maybeNumber: string | number | boolean | null | undefined
+): maybeNumber is string | number {
+ if (typeof maybeNumber === 'boolean') {
return false;
}
if (typeof maybeNumber === 'number') {
return true;
}
+ if (!maybeNumber) {
+ return false;
+ }
return /^\d+$/.test(maybeNumber);
}
From 7590847c534d0574f8c804a57e2a5371ac9424a6 Mon Sep 17 00:00:00 2001
From: Matt Quinn
Date: Tue, 24 Mar 2026 14:40:52 -0400
Subject: [PATCH 22/38] feat(performance): Add search support to EAP txn
summary sample events (#111349)
Extract `EAPSpansQueryBuilder` into a shared component and wire up
search/filtering in the Sample Events tab when using EAP mode. The spans
table now respects the search query from URL params, and non-applicable
controls (percentile filter, Open in Discover) are hidden in EAP mode.
Fixes BROWSE-463.
---------
Co-authored-by: Claude Opus 4.6
---
.../performance/eap/overviewSpansTable.tsx | 15 +--
.../transactionEvents/content.tsx | 99 +++++++++++++------
.../transactionEvents/index.tsx | 22 +++++
.../transactionEvents/utils.tsx | 32 +++++-
.../transactionOverview/content.tsx | 43 +++-----
5 files changed, 142 insertions(+), 69 deletions(-)
diff --git a/static/app/views/performance/eap/overviewSpansTable.tsx b/static/app/views/performance/eap/overviewSpansTable.tsx
index ecbac10a48cb93..94db3235e32514 100644
--- a/static/app/views/performance/eap/overviewSpansTable.tsx
+++ b/static/app/views/performance/eap/overviewSpansTable.tsx
@@ -12,6 +12,7 @@ import {t, tct} from 'sentry/locale';
import type {Organization} from 'sentry/types/organization';
import type {EventsMetaType, EventView} from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
+import {decodeScalar} from 'sentry/utils/queryString';
import type {Theme} from 'sentry/utils/theme';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useLocation} from 'sentry/utils/useLocation';
@@ -50,13 +51,15 @@ export function OverviewSpansTable({eventView, totalValues, transactionName}: Pr
const projectSlug = projects.find(p => p.id === `${eventView.project}`)?.slug;
const p95 = totalValues?.['p95()'] ?? 0;
- const defaultQuery = new MutableSearch('');
- defaultQuery.addFilterValue('is_transaction', '1');
- defaultQuery.addFilterValue('transaction', transactionName);
+ const searchQuery = decodeScalar(location.query.query, '');
- const countQuery = new MutableSearch('');
- countQuery.addFilterValue('is_transaction', '1');
- countQuery.addFilterValue('transaction', transactionName);
+ const defaultQuery = new MutableSearch(searchQuery);
+ defaultQuery.setFilterValues('is_transaction', ['true']);
+ defaultQuery.setFilterValues('transaction', [transactionName]);
+
+ const countQuery = new MutableSearch(searchQuery);
+ countQuery.setFilterValues('is_transaction', ['true']);
+ countQuery.setFilterValues('transaction', [transactionName]);
const {data: numEvents, error: numEventsError} = useSpans(
{
diff --git a/static/app/views/performance/transactionSummary/transactionEvents/content.tsx b/static/app/views/performance/transactionSummary/transactionEvents/content.tsx
index 2f3016e48e0ab2..1b37eec9c5b167 100644
--- a/static/app/views/performance/transactionSummary/transactionEvents/content.tsx
+++ b/static/app/views/performance/transactionSummary/transactionEvents/content.tsx
@@ -13,6 +13,7 @@ import {DatePageFilter} from 'sentry/components/pageFilters/date/datePageFilter'
import {EnvironmentPageFilter} from 'sentry/components/pageFilters/environment/environmentPageFilter';
import {PageFilterBar} from 'sentry/components/pageFilters/pageFilterBar';
import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
+import {useSpanSearchQueryBuilderProps} from 'sentry/components/performance/spanSearchQueryBuilder';
import {TransactionSearchQueryBuilder} from 'sentry/components/performance/transactionSearchQueryBuilder';
import {t} from 'sentry/locale';
import {DataCategory} from 'sentry/types/core';
@@ -29,6 +30,7 @@ import {useMaxPickableDays} from 'sentry/utils/useMaxPickableDays';
import {useNavigate} from 'sentry/utils/useNavigate';
import {useRoutes} from 'sentry/utils/useRoutes';
import {hasDatasetSelector} from 'sentry/views/dashboards/utils';
+import {TraceItemSearchQueryBuilder} from 'sentry/views/explore/components/traceItemSearchQueryBuilder';
import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters';
import {OverviewSpansTable} from 'sentry/views/performance/eap/overviewSpansTable';
import {useTransactionSummaryEAP} from 'sentry/views/performance/eap/useTransactionSummaryEAP';
@@ -48,6 +50,27 @@ import {EventsTable} from './eventsTable';
import type {EventsDisplayFilterName} from './utils';
import {getEventsFilterOptions} from './utils';
+function EAPSearchBar({
+ projects,
+ initialQuery,
+ onSearch,
+}: {
+ initialQuery: string;
+ onSearch: (query: string) => void;
+ projects: number[];
+}) {
+ const {spanSearchQueryBuilderProps} = useSpanSearchQueryBuilderProps({
+ projects,
+ initialQuery,
+ onSearch,
+ searchSource: 'transaction_events',
+ });
+
+ return (
+
+ );
+}
+
type Props = {
eventView: EventView;
eventsDisplayFilterName: EventsDisplayFilterName;
@@ -90,8 +113,13 @@ export function EventsContent(props: Props) {
const routes = useRoutes();
const theme = useTheme();
const domainViewFilters = useDomainViewFilters();
+ const shouldUseEAP = useTransactionSummaryEAP();
const {eventView, titles} = useMemo(() => {
+ if (shouldUseEAP) {
+ return {eventView: originalEventView, titles: []};
+ }
+
const eventViewClone = originalEventView.clone();
const transactionsListTitles = TRANSACTIONS_LIST_TITLES.slice();
const project = projects.find(p => p.id === projectId);
@@ -164,6 +192,7 @@ export function EventsContent(props: Props) {
titles: transactionsListTitles,
};
}, [
+ shouldUseEAP,
originalEventView,
location,
organization,
@@ -173,8 +202,6 @@ export function EventsContent(props: Props) {
webVital,
]);
- const shouldUseEAP = useTransactionSummaryEAP();
-
const table = shouldUseEAP ? (
-
-
- (
-
- )}
- value={eventsDisplayFilterName}
- onChange={opt => onChangeEventsDisplayFilter(opt.value)}
- options={Object.entries(eventsFilterOptions).map(([name, filter]) => ({
- value: name as EventsDisplayFilterName,
- label: filter.label,
- }))}
- />
-
+ ) : (
+
)}
- onClick={handleDiscoverButtonClick}
- >
- {t('Open in Discover')}
-
+
+ {!shouldUseEAP && (
+ (
+
+ )}
+ value={eventsDisplayFilterName}
+ onChange={opt => onChangeEventsDisplayFilter(opt.value)}
+ options={Object.entries(eventsFilterOptions).map(([name, filter]) => ({
+ value: name as EventsDisplayFilterName,
+ label: filter.label,
+ }))}
+ />
+ )}
+ {!shouldUseEAP && (
+
+ {t('Open in Discover')}
+
+ )}
);
}
diff --git a/static/app/views/performance/transactionSummary/transactionEvents/index.tsx b/static/app/views/performance/transactionSummary/transactionEvents/index.tsx
index 513784ba399835..2b92827dc30ba0 100644
--- a/static/app/views/performance/transactionSummary/transactionEvents/index.tsx
+++ b/static/app/views/performance/transactionSummary/transactionEvents/index.tsx
@@ -8,6 +8,7 @@ import {removeHistogramQueryStrings} from 'sentry/utils/performance/histogram';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {useLocation} from 'sentry/utils/useLocation';
import {useNavigate} from 'sentry/utils/useNavigate';
+import {useTransactionSummaryEAP} from 'sentry/views/performance/eap/useTransactionSummaryEAP';
import {
decodeFilterFromLocation,
filterToLocationQuery,
@@ -38,6 +39,7 @@ function TransactionEvents() {
const navigate = useNavigate();
const location = useLocation();
+ const shouldUseEAP = useTransactionSummaryEAP();
const eventsDisplayFilterName = decodeEventsDisplayFilterFromLocation(location);
const spanOperationBreakdownFilter = decodeFilterFromLocation(location);
const webVital = getWebVital(location);
@@ -121,6 +123,26 @@ function TransactionEvents() {
});
};
+ if (shouldUseEAP) {
+ return (
+
+ );
+ }
+
return (
{
@@ -230,7 +236,29 @@ export function generateTransactionEventsEventView({
}
});
- const orderby = decodeScalar(location.query.sort, '-timestamp');
+ let orderby = decodeScalar(location.query.sort, '-timestamp');
+
+ if (shouldUseEAP) {
+ orderby = orderby.replace('transaction.duration', 'span.duration');
+
+ return EventView.fromNewQueryWithLocation(
+ {
+ id: undefined,
+ version: 2,
+ name: transactionName,
+ // TODO(mjq): `fields` is never actually read - the relevant query comes
+ // from `useSegmentSpansQuery` instead. Confusingly, other fields of
+ // this EventView _are_ used in various places. Untangling this is a job
+ // for after the non-EAP branches are removed.
+ fields: [],
+ query: conditions.formatString(),
+ projects: [],
+ orderby,
+ dataset: DiscoverDatasets.SPANS,
+ },
+ location
+ );
+ }
// Default fields for relative span view
const fields = [
diff --git a/static/app/views/performance/transactionSummary/transactionOverview/content.tsx b/static/app/views/performance/transactionSummary/transactionOverview/content.tsx
index b1b3cf99a3a32d..f1753b556c16d6 100644
--- a/static/app/views/performance/transactionSummary/transactionOverview/content.tsx
+++ b/static/app/views/performance/transactionSummary/transactionOverview/content.tsx
@@ -100,27 +100,6 @@ type Props = {
export const SEGMENT_SPANS_CURSOR_NAME = 'segmentSpansCursor';
-function EAPSearchQueryBuilder({
- projects,
- initialQuery,
- onSearch,
-}: {
- initialQuery: string;
- onSearch: (query: string) => void;
- projects: number[];
-}) {
- const {spanSearchQueryBuilderProps} = useSpanSearchQueryBuilderProps({
- projects,
- initialQuery,
- onSearch,
- searchSource: 'transaction_summary',
- });
-
- return (
-
- );
-}
-
function EAPSummaryContentInner({
eventView,
location,
@@ -258,15 +237,12 @@ function EAPSummaryContentInner({
});
const datePageFilterProps = useDatePageFilterProps(maxPickableDays);
- function renderSearchBar() {
- return (
-
- );
- }
+ const {spanSearchQueryBuilderProps} = useSpanSearchQueryBuilderProps({
+ projects: projectIds,
+ initialQuery: query,
+ onSearch: handleSearch,
+ searchSource: 'transaction_summary',
+ });
return (
@@ -277,7 +253,12 @@ function EAPSummaryContentInner({
- {renderSearchBar()}
+
+
+
From 578e9980e18ab908909b288b5db5d09fa2cf80f2 Mon Sep 17 00:00:00 2001
From: Dominik Buszowiecki <44422760+DominikB2014@users.noreply.github.com>
Date: Tue, 24 Mar 2026 14:41:02 -0400
Subject: [PATCH 23/38] fix(dashboards): Align backend overview queries widget
filters with queries dashboard (#111433)
The "Queries by Time Spent" widget on the backend overview prebuilt
dashboard was filtering by `db.system:[postgresql,mysql,...]` while the
queries prebuilt dashboard used `span.category:db has:span.description`.
This mismatch meant users could see data on the queries dashboard but a
blank widget on the backend overview (or vice versa).
This extracts the shared filter into `queries/settings.ts`
(`BASE_FILTERS` / `BASE_FILTER_STRING`) and uses it consistently across
the queries dashboard, query summary dashboard, and backend overview.
Fixes DAIN-1398
---
.../backendOverview/backendOverview.ts | 4 ++--
.../utils/prebuiltConfigs/queries/queries.ts | 15 ++++-----------
.../prebuiltConfigs/queries/querySummary.ts | 19 ++++++++-----------
.../utils/prebuiltConfigs/queries/settings.ts | 10 ++++++++++
4 files changed, 24 insertions(+), 24 deletions(-)
create mode 100644 static/app/views/dashboards/utils/prebuiltConfigs/queries/settings.ts
diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/backendOverview/backendOverview.ts b/static/app/views/dashboards/utils/prebuiltConfigs/backendOverview/backendOverview.ts
index 6d4ad3d84b22a6..bc306c7a870497 100644
--- a/static/app/views/dashboards/utils/prebuiltConfigs/backendOverview/backendOverview.ts
+++ b/static/app/views/dashboards/utils/prebuiltConfigs/backendOverview/backendOverview.ts
@@ -4,9 +4,9 @@ import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {DisplayType, WidgetType, type Widget} from 'sentry/views/dashboards/types';
import type {PrebuiltDashboard} from 'sentry/views/dashboards/utils/prebuiltConfigs';
import {DASHBOARD_TITLE} from 'sentry/views/dashboards/utils/prebuiltConfigs/backendOverview/settings';
+import {BASE_FILTER_STRING} from 'sentry/views/dashboards/utils/prebuiltConfigs/queries/settings';
import {TABLE_MIN_HEIGHT} from 'sentry/views/dashboards/utils/prebuiltConfigs/settings';
import {spaceWidgetsEquallyOnRow} from 'sentry/views/dashboards/utils/prebuiltConfigs/utils/spaceWidgetsEquallyOnRow';
-import {SupportedDatabaseSystem} from 'sentry/views/insights/database/utils/constants';
import {OVERVIEW_PAGE_ALLOWED_OPS} from 'sentry/views/insights/pages/backend/settings';
import {
OVERVIEW_PAGE_ALLOWED_OPS as FRONTEND_OVERVIEW_PAGE_OPS,
@@ -152,7 +152,7 @@ export const BACKEND_OVERVIEW_SECOND_ROW_WIDGETS = spaceWidgetsEquallyOnRow(
aggregates: [`p75(${SpanFields.SPAN_DURATION})`],
columns: [SpanFields.NORMALIZED_DESCRIPTION],
fieldAliases: [''],
- conditions: `${SpanFields.DB_SYSTEM}:[${Object.values(SupportedDatabaseSystem).join(',')}]`,
+ conditions: BASE_FILTER_STRING,
orderby: `-sum(${SpanFields.SPAN_DURATION})`,
linkedDashboards: [
{
diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/queries/queries.ts b/static/app/views/dashboards/utils/prebuiltConfigs/queries/queries.ts
index a84797d74e0349..f1a34d35e0c785 100644
--- a/static/app/views/dashboards/utils/prebuiltConfigs/queries/queries.ts
+++ b/static/app/views/dashboards/utils/prebuiltConfigs/queries/queries.ts
@@ -1,23 +1,16 @@
import {t} from 'sentry/locale';
import {RATE_UNIT_TITLE, RateUnit} from 'sentry/utils/discover/fields';
import {FieldKind} from 'sentry/utils/fields';
-import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {DisplayType, WidgetType} from 'sentry/views/dashboards/types';
import type {PrebuiltDashboard} from 'sentry/views/dashboards/utils/prebuiltConfigs';
import {
AVERAGE_DURATION_TEXT,
QUERIES_PER_MINUTE_TEXT,
} from 'sentry/views/dashboards/utils/prebuiltConfigs/queries/constants';
+import {BASE_FILTER_STRING} from 'sentry/views/dashboards/utils/prebuiltConfigs/queries/settings';
import {DataTitles} from 'sentry/views/insights/common/views/spans/types';
import {ModuleName, SpanFields} from 'sentry/views/insights/types';
-export const BASE_FILTERS = {
- [SpanFields.SPAN_CATEGORY]: ModuleName.DB,
- has: SpanFields.NORMALIZED_DESCRIPTION,
-};
-
-const FILTER_STRING = MutableSearch.fromQueryObject(BASE_FILTERS).formatString();
-
export const QUERIES_PREBUILT_CONFIG: PrebuiltDashboard = {
dateCreated: '',
projects: [],
@@ -63,7 +56,7 @@ export const QUERIES_PREBUILT_CONFIG: PrebuiltDashboard = {
queries: [
{
name: QUERIES_PER_MINUTE_TEXT,
- conditions: FILTER_STRING,
+ conditions: BASE_FILTER_STRING,
fields: ['epm()'],
aggregates: ['epm()'],
columns: [],
@@ -87,7 +80,7 @@ export const QUERIES_PREBUILT_CONFIG: PrebuiltDashboard = {
queries: [
{
name: AVERAGE_DURATION_TEXT,
- conditions: FILTER_STRING,
+ conditions: BASE_FILTER_STRING,
fields: [`avg(${SpanFields.SPAN_DURATION})`],
aggregates: [`avg(${SpanFields.SPAN_DURATION})`],
columns: [],
@@ -112,7 +105,7 @@ export const QUERIES_PREBUILT_CONFIG: PrebuiltDashboard = {
queries: [
{
name: '',
- conditions: FILTER_STRING,
+ conditions: BASE_FILTER_STRING,
fields: [
SpanFields.NORMALIZED_DESCRIPTION,
'epm()',
diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/queries/querySummary.ts b/static/app/views/dashboards/utils/prebuiltConfigs/queries/querySummary.ts
index fd20801da63d7a..c50b2665ab3171 100644
--- a/static/app/views/dashboards/utils/prebuiltConfigs/queries/querySummary.ts
+++ b/static/app/views/dashboards/utils/prebuiltConfigs/queries/querySummary.ts
@@ -1,17 +1,14 @@
import {t} from 'sentry/locale';
import {FieldKind} from 'sentry/utils/fields';
-import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import {DisplayType, WidgetType} from 'sentry/views/dashboards/types';
import type {PrebuiltDashboard} from 'sentry/views/dashboards/utils/prebuiltConfigs';
import {
AVERAGE_DURATION_TEXT,
QUERIES_PER_MINUTE_TEXT,
} from 'sentry/views/dashboards/utils/prebuiltConfigs/queries/constants';
-import {BASE_FILTERS} from 'sentry/views/dashboards/utils/prebuiltConfigs/queries/queries';
+import {BASE_FILTER_STRING} from 'sentry/views/dashboards/utils/prebuiltConfigs/queries/settings';
import {ModuleName, SpanFields} from 'sentry/views/insights/types';
-const FILTER_STRING = MutableSearch.fromQueryObject(BASE_FILTERS).formatString();
-
export const QUERIES_SUMMARY_PREBUILT_CONFIG: PrebuiltDashboard = {
dateCreated: '',
projects: [],
@@ -43,7 +40,7 @@ export const QUERIES_SUMMARY_PREBUILT_CONFIG: PrebuiltDashboard = {
fields: ['epm()'],
aggregates: ['epm()'],
columns: [],
- conditions: FILTER_STRING,
+ conditions: BASE_FILTER_STRING,
orderby: '',
isHidden: false,
},
@@ -64,7 +61,7 @@ export const QUERIES_SUMMARY_PREBUILT_CONFIG: PrebuiltDashboard = {
fields: [`avg(${SpanFields.SPAN_DURATION})`],
aggregates: [`avg(${SpanFields.SPAN_DURATION})`],
columns: [],
- conditions: FILTER_STRING,
+ conditions: BASE_FILTER_STRING,
orderby: '',
isHidden: false,
},
@@ -85,7 +82,7 @@ export const QUERIES_SUMMARY_PREBUILT_CONFIG: PrebuiltDashboard = {
fields: [`sum(${SpanFields.SPAN_DURATION})`],
aggregates: [`sum(${SpanFields.SPAN_DURATION})`],
columns: [],
- conditions: FILTER_STRING,
+ conditions: BASE_FILTER_STRING,
orderby: '',
isHidden: false,
},
@@ -107,7 +104,7 @@ export const QUERIES_SUMMARY_PREBUILT_CONFIG: PrebuiltDashboard = {
aggregates: [],
columns: ['id', 'span.op', 'span.group', 'span.description', 'span.category'],
fieldAliases: [],
- conditions: FILTER_STRING,
+ conditions: BASE_FILTER_STRING,
orderby: 'id',
onDemand: [],
linkedDashboards: [],
@@ -131,7 +128,7 @@ export const QUERIES_SUMMARY_PREBUILT_CONFIG: PrebuiltDashboard = {
aggregates: ['epm()', `sum(${SpanFields.SPAN_DURATION})`],
columns: [SpanFields.TRANSACTION],
fieldAliases: [t('Found In'), t('Queries Per Minute'), t('Time Spent')],
- conditions: FILTER_STRING,
+ conditions: BASE_FILTER_STRING,
orderby: `-sum(${SpanFields.SPAN_DURATION})`,
onDemand: [],
isHidden: false,
@@ -155,7 +152,7 @@ export const QUERIES_SUMMARY_PREBUILT_CONFIG: PrebuiltDashboard = {
aggregates: ['epm()'],
columns: [],
fieldAliases: [],
- conditions: FILTER_STRING,
+ conditions: BASE_FILTER_STRING,
orderby: 'epm()',
onDemand: [],
isHidden: false,
@@ -180,7 +177,7 @@ export const QUERIES_SUMMARY_PREBUILT_CONFIG: PrebuiltDashboard = {
aggregates: [`avg(${SpanFields.SPAN_DURATION})`],
columns: [],
fieldAliases: [],
- conditions: FILTER_STRING,
+ conditions: BASE_FILTER_STRING,
orderby: `avg(${SpanFields.SPAN_DURATION})`,
onDemand: [],
isHidden: false,
diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/queries/settings.ts b/static/app/views/dashboards/utils/prebuiltConfigs/queries/settings.ts
new file mode 100644
index 00000000000000..ab2adbd97636f4
--- /dev/null
+++ b/static/app/views/dashboards/utils/prebuiltConfigs/queries/settings.ts
@@ -0,0 +1,10 @@
+import {MutableSearch} from 'sentry/utils/tokenizeSearch';
+import {ModuleName, SpanFields} from 'sentry/views/insights/types';
+
+const BASE_FILTERS = {
+ [SpanFields.SPAN_CATEGORY]: ModuleName.DB,
+ has: SpanFields.NORMALIZED_DESCRIPTION,
+};
+
+export const BASE_FILTER_STRING =
+ MutableSearch.fromQueryObject(BASE_FILTERS).formatString();
From 790a1dab540bff135882120bafcbf6dbf2254cff Mon Sep 17 00:00:00 2001
From: Jonas
Date: Tue, 24 Mar 2026 11:43:28 -0700
Subject: [PATCH 24/38] ref(nav) promote search to primary nav (#111430)
Promotes CMD+K action to primary nav when page-frame is enabled and
replaces the help menu search when cmd+k supercharged flag is enabled
Pending feature flag release, but this fixes DE-722
---------
Co-authored-by: Claude Sonnet 4.6
---
static/app/views/navigation/navigation.tsx | 17 ++++++++++++
.../app/views/navigation/primary/helpMenu.tsx | 27 ++++++++++---------
2 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/static/app/views/navigation/navigation.tsx b/static/app/views/navigation/navigation.tsx
index 97bb378af3b474..922fbec904e32f 100644
--- a/static/app/views/navigation/navigation.tsx
+++ b/static/app/views/navigation/navigation.tsx
@@ -6,9 +6,12 @@ import {Stack} from '@sentry/scraps/layout';
import {Flex} from '@sentry/scraps/layout';
import {SizeProvider} from '@sentry/scraps/sizeContext';
+import {openCommandPalette} from 'sentry/actionCreators/modal';
+import {openHelpSearchModal} from 'sentry/actionCreators/modal';
import Feature from 'sentry/components/acl/feature';
import {ErrorBoundary} from 'sentry/components/errorBoundary';
import Hook from 'sentry/components/hook';
+import {IconSearch} from 'sentry/icons';
import {
IconCompass,
IconDashboard,
@@ -297,9 +300,23 @@ export function PrimaryNavigationItems({listRef}: PrimaryNavigationItemsProps) {
*/
export function PrimaryNavigationFooterItems() {
const organization = useOrganization();
+ const hasPageFrame = useHasPageFrameFeature();
return (
+ {hasPageFrame ? (
+ ,
+ onClick: () =>
+ organization.features.includes('cmd-k-supercharged')
+ ? openCommandPalette()
+ : openHelpSearchModal({organization}),
+ }}
+ />
+ ) : null}
diff --git a/static/app/views/navigation/primary/helpMenu.tsx b/static/app/views/navigation/primary/helpMenu.tsx
index ccf5281acd8c8f..93efd4cc342b58 100644
--- a/static/app/views/navigation/primary/helpMenu.tsx
+++ b/static/app/views/navigation/primary/helpMenu.tsx
@@ -13,7 +13,6 @@ import {
IconMegaphone,
IconOpen,
IconQuestion,
- IconSearch,
IconSentry,
IconSupport,
} from 'sentry/icons';
@@ -49,18 +48,20 @@ export function PrimaryNavigationHelpMenu() {
-
-
- ) : undefined,
- onAction() {
- openHelpSearchModal({organization});
- },
- },
+ ...(hasPageFrame
+ ? // When page frame feature flag is enabled, the search menu is
+ // rendered as part of the footer items and is always visible
+ // to the user.
+ []
+ : [
+ {
+ key: 'search',
+ label: t('Search support, docs and more'),
+ onAction() {
+ openHelpSearchModal({organization});
+ },
+ },
+ ]),
...items,
{
key: 'actions',
From c7dca3e2e2bd709fa637c27df53906ab785352c4 Mon Sep 17 00:00:00 2001
From: Mihir-Mavalankar
Date: Tue, 24 Mar 2026 11:44:46 -0700
Subject: [PATCH 25/38] fix(context engine): Remove the span in the loop
(#111428)
+ Removing this span inside since it's not needed due to top level span.
---
src/sentry/tasks/seer/context_engine_index.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/sentry/tasks/seer/context_engine_index.py b/src/sentry/tasks/seer/context_engine_index.py
index ce4a3386e89ff6..f47c37f3fd5ac3 100644
--- a/src/sentry/tasks/seer/context_engine_index.py
+++ b/src/sentry/tasks/seer/context_engine_index.py
@@ -233,9 +233,8 @@ def get_allowed_org_ids_context_engine_indexing() -> list[int]:
# Ordering of these if blocks is very crucial. We want to check the hour first as
# checking the feature flag is an expensive operation and we want to avoid it if possible.
if int(md5_text(str(org.id)).hexdigest(), 16) % TOTAL_HOURLY_SLOTS == now.hour:
- with sentry_sdk.start_span(op="explorer.context_engine.has_feature"):
- if features.has("organizations:seer-explorer-context-engine", org):
- eligible_org_ids.append(org.id)
+ if features.has("organizations:seer-explorer-context-engine", org):
+ eligible_org_ids.append(org.id)
return eligible_org_ids
From 9b8fb4c766fb38ffbf5dfd9cc47b95c523f86931 Mon Sep 17 00:00:00 2001
From: Dominik Buszowiecki <44422760+DominikB2014@users.noreply.github.com>
Date: Tue, 24 Mar 2026 14:54:51 -0400
Subject: [PATCH 26/38] fix(insights): Link trace table on AI agent dashboard
to trace view (#111438)
## Summary
- On the AI agents prebuilt dashboard, the trace ID in the traces table
now links directly to the trace view with the **AI Spans** tab selected,
instead of opening a drawer.
- Adds a `linkToTraceView` prop to `TracesTable` to support this
behavior while preserving the existing drawer behavior on the agents
insights page.
Fixes DAIN-1397
## Test plan
- [ ] Navigate to the AI agents prebuilt dashboard
- [ ] Click a trace ID in the traces table
- [ ] Verify it navigates to the trace view with the AI Spans tab active
- [ ] Navigate to the agents insights page and verify the trace ID still
opens the drawer
---
.../agentsTracesTableWidgetVisualization.tsx | 5 +--
.../pages/agents/components/tracesTable.tsx | 33 ++++++++++++++++---
2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/static/app/views/dashboards/widgets/agentsTracesTableWidget/agentsTracesTableWidgetVisualization.tsx b/static/app/views/dashboards/widgets/agentsTracesTableWidget/agentsTracesTableWidgetVisualization.tsx
index a6366b25156a2f..4df837ab9af181 100644
--- a/static/app/views/dashboards/widgets/agentsTracesTableWidget/agentsTracesTableWidgetVisualization.tsx
+++ b/static/app/views/dashboards/widgets/agentsTracesTableWidget/agentsTracesTableWidgetVisualization.tsx
@@ -1,6 +1,5 @@
import type {DashboardFilters} from 'sentry/views/dashboards/types';
import {DEFAULT_TRACES_TABLE_WIDTHS} from 'sentry/views/dashboards/utils/prebuiltConfigs/ai/aiAgentsOverview';
-import {useTraceViewDrawer} from 'sentry/views/insights/pages/agents/components/drawer';
import {TracesTable} from 'sentry/views/insights/pages/agents/components/tracesTable';
interface AgentsTracesTableWidgetVisualizationProps {
@@ -16,15 +15,13 @@ export function AgentsTracesTableWidgetVisualization({
dashboardFilters,
frameless,
}: AgentsTracesTableWidgetVisualizationProps) {
- const {openTraceViewDrawer} = useTraceViewDrawer();
-
return (
);
}
diff --git a/static/app/views/insights/pages/agents/components/tracesTable.tsx b/static/app/views/insights/pages/agents/components/tracesTable.tsx
index ad3b54b35546de..034de120f006d2 100644
--- a/static/app/views/insights/pages/agents/components/tracesTable.tsx
+++ b/static/app/views/insights/pages/agents/components/tracesTable.tsx
@@ -9,6 +9,7 @@ import {Link} from '@sentry/scraps/link';
import {Text} from '@sentry/scraps/text';
import {Tooltip} from '@sentry/scraps/tooltip';
+import {normalizeDateTimeParams} from 'sentry/components/pageFilters/parse';
import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters';
import {Pagination} from 'sentry/components/pagination';
import {Placeholder} from 'sentry/components/placeholder';
@@ -49,6 +50,9 @@ import {Referrer} from 'sentry/views/insights/pages/agents/utils/referrers';
import {TableUrlParams} from 'sentry/views/insights/pages/agents/utils/urlParams';
import {DurationCell} from 'sentry/views/insights/pages/platform/shared/table/DurationCell';
import {NumberCell} from 'sentry/views/insights/pages/platform/shared/table/NumberCell';
+import {TraceViewSources} from 'sentry/views/performance/newTraceDetails/traceHeader/breadcrumbs';
+import {TraceLayoutTabKeys} from 'sentry/views/performance/newTraceDetails/useTraceLayoutTabs';
+import {getTraceDetailsUrl} from 'sentry/views/performance/traceDetails/utils';
interface TableData {
agents: string[];
@@ -92,10 +96,11 @@ const rightAlignColumns = new Set([
const DEFAULT_LIMIT = 10;
interface TracesTableProps {
- openTraceViewDrawer: ReturnType['openTraceViewDrawer'];
dashboardFilters?: DashboardFilters;
frameless?: boolean;
limit?: number;
+ linkToTraceView?: boolean;
+ openTraceViewDrawer?: ReturnType['openTraceViewDrawer'];
tableWidths?: number[];
}
@@ -105,6 +110,7 @@ export function TracesTable({
dashboardFilters,
limit = DEFAULT_LIMIT,
tableWidths,
+ linkToTraceView,
}: TracesTableProps) {
const {columns: columnOrder, handleResizeColumn} = useStateBasedColumnResize({
columns:
@@ -273,10 +279,11 @@ export function TracesTable({
dataRow={dataRow}
query={combinedQuery}
openTraceViewDrawer={openTraceViewDrawer}
+ linkToTraceView={linkToTraceView}
/>
);
},
- [combinedQuery, openTraceViewDrawer]
+ [combinedQuery, openTraceViewDrawer, linkToTraceView]
);
const additionalGridProps = frameless
@@ -324,23 +331,41 @@ const BodyCell = memo(function BodyCell({
dataRow,
query,
openTraceViewDrawer,
+ linkToTraceView,
}: {
column: GridColumnHeader;
dataRow: TableData;
- openTraceViewDrawer: (traceSlug: string, spanId?: string, timestamp?: number) => void;
query: string;
+ linkToTraceView?: boolean;
+ openTraceViewDrawer?: (traceSlug: string, spanId?: string, timestamp?: number) => void;
}) {
const organization = useOrganization();
const {selection} = usePageFilters();
+ const location = useLocation();
switch (column.key) {
case 'traceId':
+ if (linkToTraceView || !openTraceViewDrawer) {
+ const traceUrl = getTraceDetailsUrl({
+ organization,
+ traceSlug: dataRow.traceId,
+ dateSelection: normalizeDateTimeParams(selection.datetime),
+ timestamp: dataRow.timestamp / 1000,
+ location: {
+ ...location,
+ query: {},
+ },
+ source: TraceViewSources.AGENT_MONITORING,
+ tab: TraceLayoutTabKeys.AI_SPANS,
+ });
+ return {dataRow.traceId.slice(0, 8)};
+ }
return (
- openTraceViewDrawer(dataRow.traceId, undefined, dataRow.timestamp / 1000)
+ openTraceViewDrawer?.(dataRow.traceId, undefined, dataRow.timestamp / 1000)
}
>
{dataRow.traceId.slice(0, 8)}
From 42c67b9dc5964bce9709ebc371360797d3560d93 Mon Sep 17 00:00:00 2001
From: Nar Saynorath
Date: Tue, 24 Mar 2026 14:55:49 -0400
Subject: [PATCH 27/38] fix(explore): Confidence footer messages should
pluralize zero (#111436)
When there was no data, the confidence footer message would read "0 data
point" or "0 log", etc instead of "0 data points"
This PR changes it so when we look at the sample count, or normal count,
or total count, we include `0` in the criteria for displaying a plural
message.
---
.../views/explore/logs/confidenceFooter.tsx | 57 ++++++++---------
.../explore/metrics/confidenceFooter.tsx | 57 ++++++++---------
.../explore/metrics/metricGraph/index.tsx | 2 +-
.../explore/spans/charts/confidenceFooter.tsx | 64 +++++++++----------
4 files changed, 88 insertions(+), 92 deletions(-)
diff --git a/static/app/views/explore/logs/confidenceFooter.tsx b/static/app/views/explore/logs/confidenceFooter.tsx
index bec13728d477ba..77aa7209a0d45b 100644
--- a/static/app/views/explore/logs/confidenceFooter.tsx
+++ b/static/app/views/explore/logs/confidenceFooter.tsx
@@ -77,14 +77,18 @@ function ConfidenceMessage({
const isTopN = defined(topEvents) && topEvents > 1;
const noSampling = defined(isSampled) && !isSampled;
+ const usePluralSampleCount = sampleCount !== 1;
+ const usePluralNormalLogsCount =
+ defined(rawLogCounts.normal.count) && rawLogCounts.normal.count !== 1;
+ const usePluralTotalLogsCount =
+ defined(rawLogCounts.total.count) && rawLogCounts.total.count !== 1;
// No sampling happened, so don't mention estimations.
if (noSampling) {
if (!hasUserQuery) {
- const matchingLogsCount =
- sampleCount > 1
- ? t('%s logs', )
- : t('%s log', );
+ const matchingLogsCount = usePluralSampleCount
+ ? t('%s logs', )
+ : t('%s log', );
if (isTopN) {
return tct('[matchingLogsCount] for top [topEvents] groups', {
@@ -96,13 +100,12 @@ function ConfidenceMessage({
return matchingLogsCount;
}
- const matchingLogsCount =
- sampleCount > 1
- ? t('%s matches', )
- : t('%s match', );
+ const matchingLogsCount = usePluralSampleCount
+ ? t('%s matches', )
+ : t('%s match', );
const totalLogsCount = defined(rawLogCounts.total.count) ? (
- rawLogCounts.total.count > 1 ? (
+ usePluralTotalLogsCount ? (
t('%s logs', )
) : (
t('%s log', )
@@ -136,13 +139,12 @@ function ConfidenceMessage({
// partial scans means that we didnt scan all the data so it's useful
// to mention the total number of logs available
if (dataScanned === 'partial') {
- const matchingLogsCount =
- sampleCount > 1
- ? t('%s samples', )
- : t('%s sample', );
+ const matchingLogsCount = usePluralSampleCount
+ ? t('%s samples', )
+ : t('%s sample', );
const totalLogsCount = defined(rawLogCounts.total.count) ? (
- rawLogCounts.total.count > 1 ? (
+ usePluralTotalLogsCount ? (
t('%s logs', )
) : (
t('%s log', )
@@ -178,10 +180,9 @@ function ConfidenceMessage({
// otherwise, a full scan was done
// full scan means we scanned all the data available so no need to repeat that information twice
- const matchingLogsCount =
- sampleCount > 1
- ? t('%s logs', )
- : t('%s log', );
+ const matchingLogsCount = usePluralSampleCount
+ ? t('%s logs', )
+ : t('%s log', );
if (isTopN) {
return tct(
@@ -209,13 +210,12 @@ function ConfidenceMessage({
// partial scans means that we didnt scan all the data so it's useful
// to mention the total number of logs available
if (dataScanned === 'partial') {
- const matchingLogsCount =
- sampleCount > 1
- ? t('%s matches', )
- : t('%s match', );
+ const matchingLogsCount = usePluralSampleCount
+ ? t('%s matches', )
+ : t('%s match', );
const scannedLogsCount = defined(rawLogCounts.normal.count) ? (
- rawLogCounts.normal.count > 1 ? (
+ usePluralNormalLogsCount ? (
t('%s samples', )
) : (
t('%s sample', )
@@ -225,7 +225,7 @@ function ConfidenceMessage({
);
const totalLogsCount = defined(rawLogCounts.total.count) ? (
- rawLogCounts.total.count > 1 ? (
+ usePluralTotalLogsCount ? (
t('%s logs', )
) : (
t('%s log', )
@@ -263,13 +263,12 @@ function ConfidenceMessage({
// otherwise, a full scan was done
// full scan means we scanned all the data available so no need to repeat that information twice
- const matchingLogsCount =
- sampleCount > 1
- ? t('%s matches', )
- : t('%s match', );
+ const matchingLogsCount = usePluralSampleCount
+ ? t('%s matches', )
+ : t('%s match', );
const totalLogsCount = defined(rawLogCounts.total.count) ? (
- rawLogCounts.total.count > 1 ? (
+ usePluralTotalLogsCount ? (
t('%s logs', )
) : (
t('%s log', )
diff --git a/static/app/views/explore/metrics/confidenceFooter.tsx b/static/app/views/explore/metrics/confidenceFooter.tsx
index f8c316f7ea44d4..332e5f9ed3c0de 100644
--- a/static/app/views/explore/metrics/confidenceFooter.tsx
+++ b/static/app/views/explore/metrics/confidenceFooter.tsx
@@ -77,14 +77,18 @@ function ConfidenceMessage({
const isTopN = defined(topEvents) && topEvents > 1;
const noSampling = defined(isSampled) && !isSampled;
+ const usePluralSampleCount = sampleCount !== 1;
+ const usePluralNormalMetricsCount =
+ defined(rawMetricCounts.normal.count) && rawMetricCounts.normal.count !== 1;
+ const usePluralTotalMetricsCount =
+ defined(rawMetricCounts.total.count) && rawMetricCounts.total.count !== 1;
// No sampling happened, so don't mention estimations.
if (noSampling) {
if (!hasUserQuery) {
- const matchingMetricsCount =
- sampleCount > 1
- ? t('%s data points', )
- : t('%s data point', );
+ const matchingMetricsCount = usePluralSampleCount
+ ? t('%s data points', )
+ : t('%s data point', );
if (isTopN) {
return tct('[matchingMetricsCount] for top [topEvents] groups', {
@@ -96,13 +100,12 @@ function ConfidenceMessage({
return matchingMetricsCount;
}
- const matchingMetricsCount =
- sampleCount > 1
- ? t('%s matches', )
- : t('%s match', );
+ const matchingMetricsCount = usePluralSampleCount
+ ? t('%s matches', )
+ : t('%s match', );
const totalMetricsCount = defined(rawMetricCounts.total.count) ? (
- rawMetricCounts.total.count > 1 ? (
+ usePluralTotalMetricsCount ? (
t('%s data points', )
) : (
t('%s data point', )
@@ -141,13 +144,12 @@ function ConfidenceMessage({
// partial scans means that we didnt scan all the data so it's useful
// to mention the total number of metrics available
if (dataScanned === 'partial') {
- const matchingMetricsCount =
- sampleCount > 1
- ? t('%s samples', )
- : t('%s sample', );
+ const matchingMetricsCount = usePluralSampleCount
+ ? t('%s samples', )
+ : t('%s sample', );
const totalMetricsCount = defined(rawMetricCounts.total.count) ? (
- rawMetricCounts.total.count > 1 ? (
+ usePluralTotalMetricsCount ? (
t('%s data points', )
) : (
t('%s data point', )
@@ -183,10 +185,9 @@ function ConfidenceMessage({
// otherwise, a full scan was done
// full scan means we scanned all the data available so no need to repeat that information twice
- const matchingMetricsCount =
- sampleCount > 1
- ? t('%s data points', )
- : t('%s data point', );
+ const matchingMetricsCount = usePluralSampleCount
+ ? t('%s data points', )
+ : t('%s data point', );
if (isTopN) {
return tct(
@@ -214,13 +215,12 @@ function ConfidenceMessage({
// partial scans means that we didnt scan all the data so it's useful
// to mention the total number of metrics available
if (dataScanned === 'partial') {
- const matchingMetricsCount =
- sampleCount > 1
- ? t('%s matches', )
- : t('%s match', );
+ const matchingMetricsCount = usePluralSampleCount
+ ? t('%s matches', )
+ : t('%s match', );
const scannedMetricsCount = defined(rawMetricCounts.normal.count) ? (
- rawMetricCounts.normal.count > 1 || rawMetricCounts.normal.count === 0 ? (
+ usePluralNormalMetricsCount ? (
t('%s samples', )
) : (
t('%s sample', )
@@ -230,7 +230,7 @@ function ConfidenceMessage({
);
const totalMetricsCount = defined(rawMetricCounts.total.count) ? (
- rawMetricCounts.total.count > 1 ? (
+ usePluralTotalMetricsCount ? (
t('%s data points', )
) : (
t('%s data point', )
@@ -268,13 +268,12 @@ function ConfidenceMessage({
// otherwise, a full scan was done
// full scan means we scanned all the data available so no need to repeat that information twice
- const matchingMetricsCount =
- sampleCount > 1
- ? t('%s matches', )
- : t('%s match', );
+ const matchingMetricsCount = usePluralSampleCount
+ ? t('%s matches', )
+ : t('%s match', );
const totalMetricsCount = defined(rawMetricCounts.total.count) ? (
- rawMetricCounts.total.count > 1 ? (
+ usePluralTotalMetricsCount ? (
t('%s data points', )
) : (
t('%s data point', )
diff --git a/static/app/views/explore/metrics/metricGraph/index.tsx b/static/app/views/explore/metrics/metricGraph/index.tsx
index d9d8c4f8a67df6..4be1eb549ffb48 100644
--- a/static/app/views/explore/metrics/metricGraph/index.tsx
+++ b/static/app/views/explore/metrics/metricGraph/index.tsx
@@ -302,7 +302,7 @@ function Graph({
showChart && (
diff --git a/static/app/views/explore/spans/charts/confidenceFooter.tsx b/static/app/views/explore/spans/charts/confidenceFooter.tsx
index c79326f961e666..047a5082befb57 100644
--- a/static/app/views/explore/spans/charts/confidenceFooter.tsx
+++ b/static/app/views/explore/spans/charts/confidenceFooter.tsx
@@ -46,6 +46,11 @@ function confidenceMessage({
const isTopN = defined(topEvents) && topEvents > 1;
const noSampling = defined(isSampled) && !isSampled;
+ const usePluralSampleCount = sampleCount !== 1;
+ const usePluralNormalSpansCount =
+ defined(rawSpanCounts?.normal.count) && rawSpanCounts.normal.count !== 1;
+ const usePluralTotalSpansCount =
+ defined(rawSpanCounts?.total.count) && rawSpanCounts.total.count !== 1;
const maybeWarning =
confidence === 'low' ? tct('[warning] ', {warning: }) : null;
@@ -61,10 +66,9 @@ function confidenceMessage({
// The multi query mode does not fetch the raw span counts
// so make sure to have a backup when this happens.
if (!defined(rawSpanCounts)) {
- const matchingSpansCount =
- sampleCount === 1
- ? t('%s span', )
- : t('%s spans', );
+ const matchingSpansCount = usePluralSampleCount
+ ? t('%s spans', )
+ : t('%s span', );
if (isTopN) {
return tct(
@@ -92,10 +96,9 @@ function confidenceMessage({
noSampling
) {
if (!userQuery) {
- const matchingSpansCount =
- sampleCount > 1
- ? t('%s spans', )
- : t('%s span', );
+ const matchingSpansCount = usePluralSampleCount
+ ? t('%s spans', )
+ : t('%s span', );
if (isTopN) {
return tct('[matchingSpansCount] for top [topEvents] groups', {
@@ -107,13 +110,12 @@ function confidenceMessage({
return matchingSpansCount;
}
- const matchingSpansCount =
- sampleCount > 1
- ? t('%s matches', )
- : t('%s match', );
+ const matchingSpansCount = usePluralSampleCount
+ ? t('%s matches', )
+ : t('%s match', );
const totalSpansCount = defined(rawSpanCounts.total.count) ? (
- rawSpanCounts.total.count > 1 ? (
+ usePluralTotalSpansCount ? (
t('%s spans', )
) : (
t('%s span', )
@@ -142,13 +144,12 @@ function confidenceMessage({
// partial scans means that we didnt scan all the data so it's useful
// to mention the total number of spans available
if (dataScanned === 'partial') {
- const matchingSpansCount =
- sampleCount > 1
- ? t('%s samples', )
- : t('%s sample', );
+ const matchingSpansCount = usePluralSampleCount
+ ? t('%s samples', )
+ : t('%s sample', );
const totalSpansCount = defined(rawSpanCounts.total.count) ? (
- rawSpanCounts.total.count > 1 ? (
+ usePluralTotalSpansCount ? (
t('%s spans', )
) : (
t('%s span', )
@@ -184,10 +185,9 @@ function confidenceMessage({
// otherwise, a full scan was done
// full scan means we scanned all the data available so no need to repeat that information twice
- const matchingSpansCount =
- sampleCount > 1
- ? t('%s spans', )
- : t('%s span', );
+ const matchingSpansCount = usePluralSampleCount
+ ? t('%s spans', )
+ : t('%s span', );
if (isTopN) {
return tct(
@@ -215,13 +215,12 @@ function confidenceMessage({
// partial scans means that we didnt scan all the data so it's useful
// to mention the total number of spans available
if (dataScanned === 'partial') {
- const matchingSpansCount =
- sampleCount > 1
- ? t('%s matches', )
- : t('%s match', );
+ const matchingSpansCount = usePluralSampleCount
+ ? t('%s matches', )
+ : t('%s match', );
const scannedSpansCount = defined(rawSpanCounts.normal.count) ? (
- rawSpanCounts.normal.count > 1 ? (
+ usePluralNormalSpansCount ? (
t('%s samples', )
) : (
t('%s sample', )
@@ -231,7 +230,7 @@ function confidenceMessage({
);
const totalSpansCount = defined(rawSpanCounts.total.count) ? (
- rawSpanCounts.total.count > 1 ? (
+ usePluralTotalSpansCount ? (
t('%s spans', )
) : (
t('%s span', )
@@ -269,13 +268,12 @@ function confidenceMessage({
// otherwise, a full scan was done
// full scan means we scanned all the data available so no need to repeat that information twice
- const matchingSpansCount =
- sampleCount > 1
- ? t('%s matches', )
- : t('%s match', );
+ const matchingSpansCount = usePluralSampleCount
+ ? t('%s matches', )
+ : t('%s match', );
const totalSpansCount = defined(rawSpanCounts.total.count) ? (
- rawSpanCounts.total.count > 1 ? (
+ usePluralTotalSpansCount ? (
t('%s spans', )
) : (
t('%s span', )
From a5312033fbe6714fb46ce61e56e2dc1af222bce3 Mon Sep 17 00:00:00 2001
From: Lyn Nagara <1779792+lynnagara@users.noreply.github.com>
Date: Tue, 24 Mar 2026 12:26:52 -0700
Subject: [PATCH 28/38] feat(cells): locality configuration should specify cell
for new orgs (#111241)
will be used to route org provisioning to the right cell from a locality
---
src/sentry/conf/types/cell_config.py | 1 +
src/sentry/testutils/cell.py | 8 +++++++-
src/sentry/types/cell.py | 12 ++++++++++++
.../middleware/integrations/parsers/test_jira.py | 4 ++--
tests/sentry/types/test_cell.py | 2 +-
.../sentry/users/api/endpoints/test_user_regions.py | 13 ++++++++++---
6 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/src/sentry/conf/types/cell_config.py b/src/sentry/conf/types/cell_config.py
index 0268f5f37901d3..49bf08a716fb96 100644
--- a/src/sentry/conf/types/cell_config.py
+++ b/src/sentry/conf/types/cell_config.py
@@ -16,4 +16,5 @@ class LocalityConfig(TypedDict):
name: str
category: str
cells: list[str]
+ new_org_cell: str
visible: NotRequired[bool]
diff --git a/src/sentry/testutils/cell.py b/src/sentry/testutils/cell.py
index 4130b6d014a426..40a8cc8e17d9a4 100644
--- a/src/sentry/testutils/cell.py
+++ b/src/sentry/testutils/cell.py
@@ -18,7 +18,13 @@ def __init__(self, cells: Collection[Cell]) -> None:
def _apply_cells(self, cells: Collection[Cell]) -> None:
localities = frozenset(
- Locality(name=c.name, cells=frozenset([c.name]), category=c.category, visible=c.visible)
+ Locality(
+ name=c.name,
+ cells=frozenset([c.name]),
+ category=c.category,
+ visible=c.visible,
+ new_org_cell=c.name,
+ )
for c in cells
)
self._cells = frozenset(cells)
diff --git a/src/sentry/types/cell.py b/src/sentry/types/cell.py
index f6b668aa5d2eb4..25768901a9ac4d 100644
--- a/src/sentry/types/cell.py
+++ b/src/sentry/types/cell.py
@@ -36,6 +36,9 @@ class Locality:
category: RegionCategory
+ new_org_cell: str
+ """The cell within this locality where new organizations are provisioned."""
+
visible: bool = True
"""Whether the locality is visible in API responses."""
@@ -209,6 +212,13 @@ def validate_all(self) -> None:
f"cell-only={defined_cells - assigned_cells!r}"
)
+ for loc in self.localities:
+ if loc.new_org_cell not in loc.cells:
+ raise CellConfigurationError(
+ f"Locality {loc.name!r} has new_org_cell={loc.new_org_cell!r} "
+ f"which is not in its cells={set(loc.cells)!r}"
+ )
+
def _parse_raw_config(cell_config: list[CellConfig]) -> Iterable[Cell]:
for config_value in cell_config:
@@ -253,6 +263,7 @@ def _parse_locality_config(
name=config_value["name"],
category=RegionCategory(config_value["category"]),
cells=frozenset(config_value["cells"]),
+ new_org_cell=config_value["new_org_cell"],
visible=bool(config_value.get("visible", True)),
)
@@ -276,6 +287,7 @@ def load_from_config(
name=cell.name,
category=cell.category,
cells=frozenset([cell.name]),
+ new_org_cell=cell.name,
visible=cell.visible,
)
)
diff --git a/tests/sentry/middleware/integrations/parsers/test_jira.py b/tests/sentry/middleware/integrations/parsers/test_jira.py
index 48e4100e9e0db1..f0a7a38f9c8b31 100644
--- a/tests/sentry/middleware/integrations/parsers/test_jira.py
+++ b/tests/sentry/middleware/integrations/parsers/test_jira.py
@@ -20,8 +20,8 @@
region = Cell("us", 1, "http://us.testserver", RegionCategory.MULTI_TENANT)
eu_region = Cell("eu", 2, "http://eu.testserver", RegionCategory.MULTI_TENANT)
-locality = Locality("us", frozenset(["us"]), RegionCategory.MULTI_TENANT)
-eu_locality = Locality("eu", frozenset(["eu"]), RegionCategory.MULTI_TENANT)
+locality = Locality("us", frozenset(["us"]), RegionCategory.MULTI_TENANT, new_org_cell="us")
+eu_locality = Locality("eu", frozenset(["eu"]), RegionCategory.MULTI_TENANT, new_org_cell="eu")
region_config = (region, eu_region)
diff --git a/tests/sentry/types/test_cell.py b/tests/sentry/types/test_cell.py
index 1b4a13c0c99c4c..f251ddfead15b3 100644
--- a/tests/sentry/types/test_cell.py
+++ b/tests/sentry/types/test_cell.py
@@ -142,7 +142,7 @@ def test_validate_cell(self) -> None:
cell.validate()
def test_locality_to_url(self) -> None:
- locality = Locality("us", frozenset(["us"]), RegionCategory.MULTI_TENANT)
+ locality = Locality("us", frozenset(["us"]), RegionCategory.MULTI_TENANT, new_org_cell="us")
with override_settings(SILO_MODE=SiloMode.CELL, SENTRY_REGION="us"):
assert locality.to_url("/avatar/abcdef/") == "http://us.testserver/avatar/abcdef/"
with override_settings(SILO_MODE=SiloMode.CONTROL, SENTRY_REGION=""):
diff --git a/tests/sentry/users/api/endpoints/test_user_regions.py b/tests/sentry/users/api/endpoints/test_user_regions.py
index 0c818a098b90e2..196eaa6463d1a7 100644
--- a/tests/sentry/users/api/endpoints/test_user_regions.py
+++ b/tests/sentry/users/api/endpoints/test_user_regions.py
@@ -8,10 +8,17 @@
st = Cell("acme", 3, "https://acme.testserver", RegionCategory.SINGLE_TENANT)
region_config = (us, de, st)
-us_locality = Locality(name="us", cells=frozenset(["us"]), category=RegionCategory.MULTI_TENANT)
-de_locality = Locality(name="de", cells=frozenset(["de"]), category=RegionCategory.MULTI_TENANT)
+us_locality = Locality(
+ name="us", cells=frozenset(["us"]), category=RegionCategory.MULTI_TENANT, new_org_cell="us"
+)
+de_locality = Locality(
+ name="de", cells=frozenset(["de"]), category=RegionCategory.MULTI_TENANT, new_org_cell="de"
+)
st_locality = Locality(
- name="acme", cells=frozenset(["acme"]), category=RegionCategory.SINGLE_TENANT
+ name="acme",
+ cells=frozenset(["acme"]),
+ category=RegionCategory.SINGLE_TENANT,
+ new_org_cell="acme",
)
From 75ba4757ecfa3894ae253a75c0e4a87cde80ffa7 Mon Sep 17 00:00:00 2001
From: Malachi Willey
Date: Tue, 24 Mar 2026 12:41:24 -0700
Subject: [PATCH 29/38] ref(issues): Remove old issue details routes (#111437)
Some routes like /tags/ are rendered in the drawer for the new UI so can
be deleted completely. Other routes are still rendered in the main
content but reference useHasStreamlinedUI.
---
static/app/router/routes.tsx | 16 +-
.../groupMerged/groupMergedTab.tsx | 53 ---
.../groupReplays/groupReplays.tsx | 24 +-
.../groupSimilarIssuesTab.tsx | 24 -
.../groupTags/groupTagValues.spec.tsx | 138 ------
.../issueDetails/groupTags/groupTagValues.tsx | 426 ------------------
.../groupTags/groupTagsTab.spec.tsx | 83 ----
.../issueDetails/groupTags/groupTagsTab.tsx | 245 ----------
.../views/issueDetails/groupUserFeedback.tsx | 27 +-
9 files changed, 30 insertions(+), 1006 deletions(-)
delete mode 100644 static/app/views/issueDetails/groupMerged/groupMergedTab.tsx
delete mode 100644 static/app/views/issueDetails/groupSimilarIssues/groupSimilarIssuesTab.tsx
delete mode 100644 static/app/views/issueDetails/groupTags/groupTagValues.spec.tsx
delete mode 100644 static/app/views/issueDetails/groupTags/groupTagValues.tsx
delete mode 100644 static/app/views/issueDetails/groupTags/groupTagsTab.spec.tsx
delete mode 100644 static/app/views/issueDetails/groupTags/groupTagsTab.tsx
diff --git a/static/app/router/routes.tsx b/static/app/router/routes.tsx
index 0d617cc100f316..23ddd007d88199 100644
--- a/static/app/router/routes.tsx
+++ b/static/app/router/routes.tsx
@@ -2453,11 +2453,17 @@ function buildRoutes(): RouteObject[] {
},
{
path: TabPaths[Tab.DISTRIBUTIONS],
- component: make(() => import('sentry/views/issueDetails/groupTags/groupTagsTab')),
+ component: make(
+ () => import('sentry/views/issueDetails/groupEventDetails/groupEventDetails'),
+
+ ),
},
{
path: `${TabPaths[Tab.DISTRIBUTIONS]}:tagKey/`,
- component: make(() => import('sentry/views/issueDetails/groupTags/groupTagValues')),
+ component: make(
+ () => import('sentry/views/issueDetails/groupEventDetails/groupEventDetails'),
+
+ ),
},
{
path: TabPaths[Tab.USER_FEEDBACK],
@@ -2470,13 +2476,15 @@ function buildRoutes(): RouteObject[] {
{
path: TabPaths[Tab.SIMILAR_ISSUES],
component: make(
- () => import('sentry/views/issueDetails/groupSimilarIssues/groupSimilarIssuesTab')
+ () => import('sentry/views/issueDetails/groupEventDetails/groupEventDetails'),
+
),
},
{
path: TabPaths[Tab.MERGED],
component: make(
- () => import('sentry/views/issueDetails/groupMerged/groupMergedTab')
+ () => import('sentry/views/issueDetails/groupEventDetails/groupEventDetails'),
+
),
},
];
diff --git a/static/app/views/issueDetails/groupMerged/groupMergedTab.tsx b/static/app/views/issueDetails/groupMerged/groupMergedTab.tsx
deleted file mode 100644
index 3c97fa193fd06d..00000000000000
--- a/static/app/views/issueDetails/groupMerged/groupMergedTab.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import * as Layout from 'sentry/components/layouts/thirds';
-import {LoadingError} from 'sentry/components/loadingError';
-import {LoadingIndicator} from 'sentry/components/loadingIndicator';
-import type {Group} from 'sentry/types/group';
-import {useLocation} from 'sentry/utils/useLocation';
-import {useOrganization} from 'sentry/utils/useOrganization';
-import {useParams} from 'sentry/utils/useParams';
-import {useProjectFromSlug} from 'sentry/utils/useProjectFromSlug';
-import GroupEventDetails from 'sentry/views/issueDetails/groupEventDetails/groupEventDetails';
-import {GroupMergedView} from 'sentry/views/issueDetails/groupMerged';
-import {useGroup} from 'sentry/views/issueDetails/useGroup';
-import {useHasStreamlinedUI} from 'sentry/views/issueDetails/utils';
-
-function GroupMergedTab() {
- const params = useParams<{groupId: Group['id']}>();
- const location = useLocation();
- const hasStreamlinedUI = useHasStreamlinedUI();
- const organization = useOrganization();
-
- const {
- data: group,
- isPending: isGroupPending,
- isError: isGroupError,
- refetch: refetchGroup,
- } = useGroup({groupId: params.groupId});
- const project = useProjectFromSlug({
- organization,
- projectSlug: group?.project.slug,
- });
-
- // TODO(streamline-ui): Point router to event details page since merged issues opens in a drawer.
- if (hasStreamlinedUI) {
- return ;
- }
-
- if (isGroupPending || !project) {
- return ;
- }
-
- if (isGroupError) {
- return ;
- }
-
- return (
-
-
-
-
-
- );
-}
-
-export default GroupMergedTab;
diff --git a/static/app/views/issueDetails/groupReplays/groupReplays.tsx b/static/app/views/issueDetails/groupReplays/groupReplays.tsx
index 8481615d775f9e..fb23253dcae55c 100644
--- a/static/app/views/issueDetails/groupReplays/groupReplays.tsx
+++ b/static/app/views/issueDetails/groupReplays/groupReplays.tsx
@@ -1,5 +1,4 @@
import {Fragment, useEffect, useMemo} from 'react';
-import {css} from '@emotion/react';
import styled from '@emotion/styled';
import type {Location, Query} from 'history';
@@ -43,7 +42,6 @@ import {useLocation} from 'sentry/utils/useLocation';
import {useOrganization} from 'sentry/utils/useOrganization';
import {useParams} from 'sentry/utils/useParams';
import {GroupReplaysPlayer} from 'sentry/views/issueDetails/groupReplays/groupReplaysPlayer';
-import {useHasStreamlinedUI} from 'sentry/views/issueDetails/utils';
import {useAllMobileProj} from 'sentry/views/replays/detail/useAllMobileProj';
import type {ReplayListLocationQuery, ReplayListRecord} from 'sentry/views/replays/types';
@@ -92,7 +90,6 @@ export function GroupReplays({group}: Props) {
function GroupReplaysContent({group}: Props) {
const organization = useOrganization();
const location = useLocation();
- const hasStreamlinedUI = useHasStreamlinedUI();
const {eventView, fetchError, isFetching} = useReplaysFromIssue({
group,
@@ -121,9 +118,9 @@ function GroupReplaysContent({group}: Props) {
if (!eventView) {
// Shown on load and no replay data available
return (
-
+
- {hasStreamlinedUI ? : null}
+
{isFetching ? (
@@ -148,9 +145,9 @@ function GroupReplaysContent({group}: Props) {
return (
-
+
- {hasStreamlinedUI ? : null}
+
{replayCount > 50
@@ -328,17 +325,12 @@ function ReplayOverlay({
);
}
-const StyledLayoutPage = styled(Layout.Page)<{hasStreamlinedUI?: boolean}>`
+const StyledLayoutPage = styled(Layout.Page)`
background-color: ${p => p.theme.tokens.background.primary};
gap: ${p => p.theme.space.lg};
-
- ${p =>
- p.hasStreamlinedUI &&
- css`
- border: 1px solid ${p.theme.tokens.border.primary};
- border-radius: ${p.theme.radius.md};
- padding: ${p.theme.space.lg};
- `}
+ border: 1px solid ${p => p.theme.tokens.border.primary};
+ border-radius: ${p => p.theme.radius.md};
+ padding: ${p => p.theme.space.lg};
`;
const StyledBreak = styled('hr')`
diff --git a/static/app/views/issueDetails/groupSimilarIssues/groupSimilarIssuesTab.tsx b/static/app/views/issueDetails/groupSimilarIssues/groupSimilarIssuesTab.tsx
deleted file mode 100644
index fc23c8ffc6391e..00000000000000
--- a/static/app/views/issueDetails/groupSimilarIssues/groupSimilarIssuesTab.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import * as Layout from 'sentry/components/layouts/thirds';
-import GroupEventDetails from 'sentry/views/issueDetails/groupEventDetails/groupEventDetails';
-import {GroupSimilarIssues} from 'sentry/views/issueDetails/groupSimilarIssues/similarIssues';
-import {useHasStreamlinedUI} from 'sentry/views/issueDetails/utils';
-
-function GroupSimilarIssuesTab() {
- const hasStreamlinedUI = useHasStreamlinedUI();
-
- // TODO(streamlined-ui): Remove this component and point router to GroupEventDetails
- // Similar issues will open in a drawer
- if (hasStreamlinedUI) {
- return ;
- }
-
- return (
-
-
-
-
-
- );
-}
-
-export default GroupSimilarIssuesTab;
diff --git a/static/app/views/issueDetails/groupTags/groupTagValues.spec.tsx b/static/app/views/issueDetails/groupTags/groupTagValues.spec.tsx
deleted file mode 100644
index c1c6df66741324..00000000000000
--- a/static/app/views/issueDetails/groupTags/groupTagValues.spec.tsx
+++ /dev/null
@@ -1,138 +0,0 @@
-import {GroupFixture} from 'sentry-fixture/group';
-import {ProjectFixture} from 'sentry-fixture/project';
-import {TagsFixture} from 'sentry-fixture/tags';
-import {TagValuesFixture} from 'sentry-fixture/tagvalues';
-
-import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
-
-import {ProjectsStore} from 'sentry/stores/projectsStore';
-import {GroupTagValues} from 'sentry/views/issueDetails/groupTags/groupTagValues';
-
-describe('GroupTagValues', () => {
- const group = GroupFixture();
- const tags = TagsFixture();
- const project = ProjectFixture();
-
- const makeInitialRouterConfig = (tagKey: string, environment?: string[] | string) => ({
- location: {
- pathname: `/organizations/org-slug/issues/${group.id}/tags/${tagKey}/`,
- query: {
- ...(environment && {environment}),
- },
- },
- route: '/organizations/:orgId/issues/:groupId/tags/:tagKey/',
- });
-
- beforeEach(() => {
- ProjectsStore.init();
- ProjectsStore.loadInitialData([project]);
- MockApiClient.addMockResponse({
- url: `/organizations/org-slug/issues/${group.id}/`,
- body: group,
- });
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/issues/1/tags/user/',
- body: tags.find(({key}) => key === 'user'),
- });
- });
-
- afterEach(() => {
- MockApiClient.clearMockResponses();
- });
-
- it('renders a list of tag values', async () => {
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/issues/1/tags/user/values/',
- body: TagValuesFixture(),
- });
- render(, {
- initialRouterConfig: makeInitialRouterConfig('user'),
- });
-
- // Special case for user tag - column title changes to Affected Users
- expect(await screen.findByText('Affected Users')).toBeInTheDocument();
-
- // Affected user column
- expect(screen.getByText('David Cramer')).toBeInTheDocument();
- // Percent column
- expect(screen.getByText('16.67%')).toBeInTheDocument();
- // Count column
- expect(screen.getByText('3')).toBeInTheDocument();
- });
-
- it('can page through tag values', async () => {
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/issues/1/tags/user/values/',
- body: TagValuesFixture(),
- headers: {
- Link:
- '; rel="previous"; results="false"; cursor="0:0:1", ' +
- '; rel="next"; results="true"; cursor="0:100:0"',
- },
- });
- const {router} = render(, {
- initialRouterConfig: makeInitialRouterConfig('user'),
- });
-
- expect(await screen.findByRole('button', {name: 'Previous'})).toBeDisabled();
- expect(screen.getByRole('button', {name: 'Next'})).toBeEnabled();
-
- // Clicking next button loads page with query param ?cursor=0:100:0
- await userEvent.click(screen.getByRole('button', {name: 'Next'}));
- await waitFor(() => {
- expect(router.location.query.cursor).toBe('0:100:0');
- });
- });
-
- it('navigates to issue details events tab with correct query params', async () => {
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/issues/1/tags/user/values/',
- body: TagValuesFixture(),
- });
- const {router} = render(, {
- initialRouterConfig: makeInitialRouterConfig('user'),
- });
-
- await userEvent.click(await screen.findByRole('button', {name: 'More'}));
- await userEvent.click(
- screen.getByRole('menuitemradio', {name: 'Search All Issues with Tag Value'})
- );
-
- await waitFor(() => {
- expect(router.location.pathname).toBe('/organizations/org-slug/issues/');
- });
- expect(router.location.query.query).toBe('user.username:david');
- });
-
- it('renders an error message if tag values request fails', async () => {
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/issues/1/tags/user/values/',
- statusCode: 500,
- });
-
- render(, {
- initialRouterConfig: makeInitialRouterConfig('user', 'staging'),
- });
-
- expect(
- await screen.findByText('There was an error loading tag details')
- ).toBeInTheDocument();
- });
-
- it('renders an error message if no tag values are returned because of environment selection', async () => {
- MockApiClient.addMockResponse({
- url: '/organizations/org-slug/issues/1/tags/user/values/',
- body: [],
- });
-
- render(, {
- initialRouterConfig: makeInitialRouterConfig('user', 'staging'),
- });
-
- expect(
- await screen.findByText(
- 'No tags were found for the currently selected environments'
- )
- ).toBeInTheDocument();
- });
-});
diff --git a/static/app/views/issueDetails/groupTags/groupTagValues.tsx b/static/app/views/issueDetails/groupTags/groupTagValues.tsx
deleted file mode 100644
index cb5a14ca76fd10..00000000000000
--- a/static/app/views/issueDetails/groupTags/groupTagValues.tsx
+++ /dev/null
@@ -1,426 +0,0 @@
-import {Fragment, useEffect} from 'react';
-import styled from '@emotion/styled';
-
-import {LinkButton} from '@sentry/scraps/button';
-import type {FlexProps} from '@sentry/scraps/layout';
-import {Flex, Grid} from '@sentry/scraps/layout';
-import {ExternalLink, Link} from '@sentry/scraps/link';
-
-import {useFetchIssueTag, useFetchIssueTagValues} from 'sentry/actionCreators/group';
-import {addMessage} from 'sentry/actionCreators/indicator';
-import {DataExport, ExportQueryType} from 'sentry/components/dataExport';
-import {DeviceName} from 'sentry/components/deviceName';
-import {DropdownMenu} from 'sentry/components/dropdownMenu';
-import {UserBadge} from 'sentry/components/idBadge/userBadge';
-import * as Layout from 'sentry/components/layouts/thirds';
-import {LoadingError} from 'sentry/components/loadingError';
-import {LoadingIndicator} from 'sentry/components/loadingIndicator';
-import {extractSelectionParameters} from 'sentry/components/pageFilters/parse';
-import {Pagination} from 'sentry/components/pagination';
-import {PanelTable} from 'sentry/components/panels/panelTable';
-import {TimeSince} from 'sentry/components/timeSince';
-import {IconArrow, IconEllipsis, IconMail, IconOpen} from 'sentry/icons';
-import {t} from 'sentry/locale';
-import type {SavedQueryVersions} from 'sentry/types/organization';
-import {percent} from 'sentry/utils';
-import {EventView} from 'sentry/utils/discover/eventView';
-import {SavedQueryDatasets} from 'sentry/utils/discover/types';
-import {isUrl} from 'sentry/utils/string/isUrl';
-import {useLocation} from 'sentry/utils/useLocation';
-import {useOrganization} from 'sentry/utils/useOrganization';
-import {useParams} from 'sentry/utils/useParams';
-import {useProjectFromSlug} from 'sentry/utils/useProjectFromSlug';
-import {hasDatasetSelector} from 'sentry/views/dashboards/utils';
-import GroupEventDetails from 'sentry/views/issueDetails/groupEventDetails/groupEventDetails';
-import {useGroup} from 'sentry/views/issueDetails/useGroup';
-import {useGroupDetailsRoute} from 'sentry/views/issueDetails/useGroupDetailsRoute';
-import {
- useEnvironmentsFromUrl,
- useHasStreamlinedUI,
-} from 'sentry/views/issueDetails/utils';
-
-type RouteParams = {
- groupId: string;
- orgId: string;
- tagKey?: string;
-};
-
-const DEFAULT_SORT = 'count';
-
-function useTagQueries({
- groupId,
- tagKey,
- environments,
- sort,
- cursor,
-}: {
- environments: string[];
- groupId: string;
- sort: string | string[];
- tagKey: string;
- cursor?: string;
-}) {
- const organization = useOrganization();
-
- const {
- data: tagValueList,
- isPending: tagValueListIsLoading,
- isError: tagValueListIsError,
- getResponseHeader,
- } = useFetchIssueTagValues({
- orgSlug: organization.slug,
- groupId,
- tagKey,
- environment: environments,
- sort,
- cursor,
- });
- const {data: tag, isError: tagIsError} = useFetchIssueTag({
- orgSlug: organization.slug,
- groupId,
- tagKey,
- });
-
- useEffect(() => {
- if (tagIsError) {
- addMessage(t('Failed to fetch total tag values'), 'error');
- }
- }, [tagIsError]);
-
- return {
- tagValueList,
- tag,
- isLoading: tagValueListIsLoading,
- isError: tagValueListIsError,
- pageLinks: getResponseHeader?.('Link'),
- };
-}
-
-export function GroupTagValues() {
- const organization = useOrganization();
- const location = useLocation();
- const params = useParams();
- const environments = useEnvironmentsFromUrl();
- const {baseUrl} = useGroupDetailsRoute();
- const {orgId, tagKey = ''} = useParams();
- const {cursor, page: _page, ...currentQuery} = location.query;
-
- const {
- data: group,
- isPending: isGroupPending,
- isError: isGroupError,
- refetch: refetchGroup,
- } = useGroup({groupId: params.groupId});
- const project = useProjectFromSlug({organization, projectSlug: group?.project?.slug});
-
- const title = tagKey === 'user' ? t('Affected Users') : tagKey;
- const sort = location.query.sort || DEFAULT_SORT;
- const sortArrow = ;
-
- const {tagValueList, tag, isLoading, isError, pageLinks} = useTagQueries({
- groupId: params.groupId,
- sort,
- tagKey,
- environments,
- cursor: typeof cursor === 'string' ? cursor : undefined,
- });
-
- if (isGroupPending) {
- return ;
- }
-
- if (isGroupError) {
- return (
-
- );
- }
-
- const lastSeenColumnHeader = (
-
- {t('Last Seen')} {sort === 'date' && sortArrow}
-
- );
- const countColumnHeader = (
-
- {t('Count')} {sort === 'count' && sortArrow}
-
- );
- const renderResults = () => {
- if (isError) {
- return ;
- }
-
- if (isLoading) {
- return null;
- }
-
- const discoverFields = [
- 'title',
- 'release',
- 'environment',
- 'user.display',
- 'timestamp',
- ];
-
- const globalSelectionParams = extractSelectionParameters(location.query);
- return tagValueList?.map((tagValue, tagValueIdx) => {
- const pct = tag?.totalValues
- ? `${percent(tagValue.count, tag?.totalValues).toFixed(2)}%`
- : '--';
- const key = tagValue.key ?? tagKey;
- const issuesQuery = tagValue.query || `${key}:"${tagValue.value}"`;
- const discoverView = EventView.fromSavedQuery({
- id: undefined,
- name: key ?? '',
- fields: [
- ...(key === undefined ? [] : [key]),
- ...discoverFields.filter(field => field !== key),
- ],
- orderby: '-timestamp',
- query: `issue:${group.shortId} ${issuesQuery}`,
- projects: [Number(project?.id)],
- environment: environments,
- version: 2 as SavedQueryVersions,
- range: '90d',
- });
- const issuesPath = `/organizations/${orgId}/issues/`;
- const tagName = tagValue.name === '' ? t('(empty)') : tagValue.name;
-
- return (
-
-
-
-
- {key === 'user' ? (
-
- ) : (
-
- )}
-
-
-
- {tagValue.email && (
-
-
-
- )}
- {isUrl(tagValue.value) && (
-
-
-
- )}
-
- {pct}
- {tagValue.count.toLocaleString()}
-
-
-
-
- ,
- 'aria-label': t('More'),
- }}
- items={[
- {
- key: 'open-in-discover',
- label: t('Open in Discover'),
- to: discoverView.getResultsViewUrlTarget(
- organization,
- false,
- hasDatasetSelector(organization)
- ? SavedQueryDatasets.ERRORS
- : undefined
- ),
- hidden: !organization.features.includes('discover-basic'),
- },
- {
- key: 'search-issues',
- label: t('Search All Issues with Tag Value'),
- to: {
- pathname: issuesPath,
- query: {
- ...globalSelectionParams, // preserve page filter selections
- query: issuesQuery,
- },
- },
- },
- ]}
- />
-
-
- );
- });
- };
-
- return (
-
-
-
- {t('Tag Details')}
-
-