From 9416ed44befa410f21909b8d4b9e5ac478af3321 Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Fri, 3 Jul 2026 15:35:25 -0400 Subject: [PATCH 1/4] hide discover tabs and change page title --- .../views/discover/results/resultsHeader.tsx | 17 ++++++++++------- static/app/views/discover/utils.tsx | 4 ++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/static/app/views/discover/results/resultsHeader.tsx b/static/app/views/discover/results/resultsHeader.tsx index e6951daf8028..b70ba828a296 100644 --- a/static/app/views/discover/results/resultsHeader.tsx +++ b/static/app/views/discover/results/resultsHeader.tsx @@ -16,6 +16,7 @@ import {DiscoverBreadcrumb} from 'sentry/views/discover/breadcrumb'; import SavedQueryButtonGroup from 'sentry/views/discover/savedQuery'; import {DatasetSelectorTabs} from 'sentry/views/discover/savedQuery/datasetSelectorTabs'; import {getSavedQueryWithDataset} from 'sentry/views/discover/savedQuery/utils'; +import {getTransactionsDeprecation} from 'sentry/views/discover/utils'; import {TopBar} from 'sentry/views/navigation/topBar'; type Props = { @@ -103,7 +104,7 @@ function ResultsHeaderBase({ const title = ( - {t('Discover')} + {getTransactionsDeprecation(organization) ? t('Errors') : t('Discover')} {savedQueryButton} - + {!getTransactionsDeprecation(organization) && ( + + )} ); } diff --git a/static/app/views/discover/utils.tsx b/static/app/views/discover/utils.tsx index 761bcb69dcf1..c391dbdc9881 100644 --- a/static/app/views/discover/utils.tsx +++ b/static/app/views/discover/utils.tsx @@ -903,3 +903,7 @@ export const SAVED_QUERY_DATASET_TO_WIDGET_TYPE = { [SavedQueryDatasets.ERRORS]: WidgetType.ERRORS, [SavedQueryDatasets.TRANSACTIONS]: WidgetType.TRANSACTIONS, }; + +export function getTransactionsDeprecation(organization: Organization) { + return organization.features.includes('discover-saved-queries-deprecation'); +} From a4bb70fb8764a9928fc5826555fe4f6ba0822e0f Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Mon, 6 Jul 2026 12:14:49 -0400 Subject: [PATCH 2/4] feat(discover): remove transactions and surface errors --- .../ui/commandPaletteGlobalActions.tsx | 24 +++++++++++++---- static/app/router/routes.tsx | 21 +++++++++------ static/app/views/discover/index.tsx | 26 ++++++++++++++++++- static/app/views/discover/pathnames.tsx | 6 ++++- .../views/discover/results/resultsHeader.tsx | 22 +++++++++++++++- .../explore/exploreSecondaryNavigation.tsx | 26 ++++++++++++++----- 6 files changed, 103 insertions(+), 22 deletions(-) diff --git a/static/app/components/commandPalette/ui/commandPaletteGlobalActions.tsx b/static/app/components/commandPalette/ui/commandPaletteGlobalActions.tsx index 52756e491181..77ab14dc1662 100644 --- a/static/app/components/commandPalette/ui/commandPaletteGlobalActions.tsx +++ b/static/app/components/commandPalette/ui/commandPaletteGlobalActions.tsx @@ -107,6 +107,8 @@ export function isNavItemVisible( } return typeof item.show === 'function' ? item.show(context) : item.show; } +import {getTransactionsDeprecation} from 'sentry/views/discover/utils'; + import {CMDKAction} from './cmdk'; import {CommandPaletteSlot} from './commandPaletteSlot'; import {useCommandPaletteState} from './commandPaletteStateContext'; @@ -381,12 +383,24 @@ export function GlobalCommandPaletteActions() { to={`${prefix}/explore/metrics/`} /> )} - {organization.features.includes('explore-errors') && ( - - )} + {organization.features.includes('explore-errors') && + !getTransactionsDeprecation(organization) && ( + + )} {organization.features.includes('profiling') && ( import('sentry/views/discover/eventDetails')), }, ]; - const discoverRoutes: SentryRouteObject = { - path: '/discover/', + const discoverErrorsRoutes: SentryRouteObject = { + path: '/errors/', component: make(() => import('sentry/views/discover')), withOrgPath: true, - children: discoverChildren, + children: discoverErrorsChildren, }; const errorsChildren: SentryRouteObject[] = [ @@ -1711,7 +1711,7 @@ function buildRoutes(): RouteObject[] { }, ]; const errorsRoutes: SentryRouteObject = { - path: '/errors/', + path: '/errors-v2/', component: make(() => import('sentry/views/explore/errors')), withOrgPath: true, children: errorsChildren, @@ -2267,10 +2267,15 @@ function buildRoutes(): RouteObject[] { component: make(() => import('sentry/views/explore/replays/index')), children: replayChildren, }, + { + path: 'errors/', + component: make(() => import('sentry/views/discover')), + children: discoverErrorsChildren, + }, { path: 'discover/', component: make(() => import('sentry/views/discover')), - children: discoverChildren, + children: discoverErrorsChildren, }, { path: 'releases/', @@ -2306,7 +2311,7 @@ function buildRoutes(): RouteObject[] { ], }, { - path: 'errors/', + path: 'errors-v2/', component: make(() => import('sentry/views/explore/errors')), children: errorsChildren, }, @@ -2779,7 +2784,7 @@ function buildRoutes(): RouteObject[] { releasesRoutes, snapshotsRedirect, statsRoutes, - discoverRoutes, + discoverErrorsRoutes, errorsRoutes, performanceRoutes, domainViewRoutes, diff --git a/static/app/views/discover/index.tsx b/static/app/views/discover/index.tsx index 4d3065696913..dc78f00aa902 100644 --- a/static/app/views/discover/index.tsx +++ b/static/app/views/discover/index.tsx @@ -8,20 +8,44 @@ import {AnalyticsArea} from 'sentry/components/analyticsArea'; import {NoProjectMessage} from 'sentry/components/noProjectMessage'; import {Redirect} from 'sentry/components/redirect'; import {t} from 'sentry/locale'; +import {useLocation} from 'sentry/utils/useLocation'; import {useOrganization} from 'sentry/utils/useOrganization'; +import {makeDiscoverPathname} from 'sentry/views/discover/pathnames'; +import {getTransactionsDeprecation} from 'sentry/views/discover/utils'; import {useRedirectNavigationV2Routes} from 'sentry/views/navigation/useRedirectNavigationV2Routes'; function DiscoverContainer() { const organization = useOrganization(); + const location = useLocation(); + const discoverTransactionsDeprecation = getTransactionsDeprecation(organization); const redirectPath = useRedirectNavigationV2Routes({ oldPathPrefix: '/discover/', - newPathPrefix: '/explore/discover/', + newPathPrefix: discoverTransactionsDeprecation + ? '/explore/errors/' + : '/explore/discover/', }); if (redirectPath) { return ; } + // Tranasctions deprecation redirects + if ( + discoverTransactionsDeprecation && + location.pathname.includes('/explore/discover/') + ) { + // errors dataset redirects to new errors url and keeps the same query params + if (location.query.dataset === 'errors') { + const targetPath = makeDiscoverPathname({ + path: '/homepage/', + organization, + }); + return ; + } + // transactions dataset redirects to traces url as we don't support transactions anymore + return ; + } + function renderNoAccess() { return ( diff --git a/static/app/views/discover/pathnames.tsx b/static/app/views/discover/pathnames.tsx index 17a92a91489b..c7f7770c6a20 100644 --- a/static/app/views/discover/pathnames.tsx +++ b/static/app/views/discover/pathnames.tsx @@ -1,7 +1,9 @@ import type {Organization} from 'sentry/types/organization'; import {normalizeUrl} from 'sentry/utils/url/normalizeUrl'; +import {getTransactionsDeprecation} from 'sentry/views/discover/utils'; const DISCOVER_BASE_PATHNAME = 'explore/discover'; +const ERRORS_BASE_PATHNAME = 'explore/errors'; export function makeDiscoverPathname({ path, @@ -11,6 +13,8 @@ export function makeDiscoverPathname({ path: '/' | `/${string}/`; }) { return normalizeUrl( - `/organizations/${organization.slug}/${DISCOVER_BASE_PATHNAME}${path}` + getTransactionsDeprecation(organization) + ? `/organizations/${organization.slug}/${ERRORS_BASE_PATHNAME}${path}` + : `/organizations/${organization.slug}/${DISCOVER_BASE_PATHNAME}${path}` ); } diff --git a/static/app/views/discover/results/resultsHeader.tsx b/static/app/views/discover/results/resultsHeader.tsx index b70ba828a296..dd977c102ec6 100644 --- a/static/app/views/discover/results/resultsHeader.tsx +++ b/static/app/views/discover/results/resultsHeader.tsx @@ -1,6 +1,8 @@ import {Fragment, useCallback, useEffect, useState} from 'react'; import type {Location} from 'history'; +import type {ContainerProps} from '@sentry/scraps/layout'; + import {fetchHomepageQuery} from 'sentry/actionCreators/discoverHomepageQueries'; import {fetchSavedQuery} from 'sentry/actionCreators/discoverSavedQueries'; import type {Client} from 'sentry/api'; @@ -122,8 +124,26 @@ function ResultsHeaderBase({ /> ); + // there's some styling that gets messed up when choosing to not render the + // dataset selector tabs so i'm injecting some styles fix it. This should be removed + // when the dataset selector tabs are removed. + const deprecationHeaderStyles: ContainerProps<'header'> = { + padding: { + 'screen:sm': '0', + 'screen:md': '0', + }, + borderBottom: { + '2xs': 'none', + xs: 'none', + sm: 'none', + md: 'none', + }, + }; + return ( - + {isHomepage ? ( {title} diff --git a/static/app/views/navigation/secondary/sections/explore/exploreSecondaryNavigation.tsx b/static/app/views/navigation/secondary/sections/explore/exploreSecondaryNavigation.tsx index da0fddb4d2a5..4fa542a4b26a 100644 --- a/static/app/views/navigation/secondary/sections/explore/exploreSecondaryNavigation.tsx +++ b/static/app/views/navigation/secondary/sections/explore/exploreSecondaryNavigation.tsx @@ -5,6 +5,7 @@ import {FeatureBadge} from '@sentry/scraps/badge'; import Feature from 'sentry/components/acl/feature'; import {t} from 'sentry/locale'; import {useOrganization} from 'sentry/utils/useOrganization'; +import {getTransactionsDeprecation} from 'sentry/views/discover/utils'; import {CONVERSATIONS_LANDING_SUB_PATH} from 'sentry/views/explore/conversations/settings'; import { MAX_STARRED_SAVED_QUERIES_IN_NAV, @@ -23,6 +24,8 @@ export function ExploreSecondaryNavigation() { perPage: MAX_STARRED_SAVED_QUERIES_IN_NAV, }); + const discoverTransactionsDeprecation = getTransactionsDeprecation(organization); + return ( {t('Explore')} @@ -62,11 +65,14 @@ export function ExploreSecondaryNavigation() { - + } > @@ -80,11 +86,19 @@ export function ExploreSecondaryNavigation() { > - {t('Discover')} + {discoverTransactionsDeprecation ? t('Errors') : t('Discover')} From 50ff58a7111b74a041e355a5abdd8de04969372c Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Mon, 6 Jul 2026 13:41:29 -0400 Subject: [PATCH 3/4] cursor fixes + acceptance tests (hopefully) --- static/app/router/routes.tsx | 2 +- static/app/views/discover/index.tsx | 17 +++++++++++++---- .../explore/exploreSecondaryNavigation.tsx | 5 +---- tests/acceptance/test_organization_events_v2.py | 4 ++-- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/static/app/router/routes.tsx b/static/app/router/routes.tsx index e8ece86dcb85..df2571fa6e7c 100644 --- a/static/app/router/routes.tsx +++ b/static/app/router/routes.tsx @@ -1698,7 +1698,7 @@ function buildRoutes(): RouteObject[] { }, ]; const discoverErrorsRoutes: SentryRouteObject = { - path: '/errors/', + path: '/discover/', component: make(() => import('sentry/views/discover')), withOrgPath: true, children: discoverErrorsChildren, diff --git a/static/app/views/discover/index.tsx b/static/app/views/discover/index.tsx index dc78f00aa902..27bcaa969c6f 100644 --- a/static/app/views/discover/index.tsx +++ b/static/app/views/discover/index.tsx @@ -8,8 +8,11 @@ import {AnalyticsArea} from 'sentry/components/analyticsArea'; import {NoProjectMessage} from 'sentry/components/noProjectMessage'; import {Redirect} from 'sentry/components/redirect'; import {t} from 'sentry/locale'; +import {SavedQueryDatasets} from 'sentry/utils/discover/types'; +import {normalizeUrl} from 'sentry/utils/url/normalizeUrl'; import {useLocation} from 'sentry/utils/useLocation'; import {useOrganization} from 'sentry/utils/useOrganization'; +import {Dataset} from 'sentry/views/alerts/rules/metric/types'; import {makeDiscoverPathname} from 'sentry/views/discover/pathnames'; import {getTransactionsDeprecation} from 'sentry/views/discover/utils'; import {useRedirectNavigationV2Routes} from 'sentry/views/navigation/useRedirectNavigationV2Routes'; @@ -34,16 +37,22 @@ function DiscoverContainer() { discoverTransactionsDeprecation && location.pathname.includes('/explore/discover/') ) { - // errors dataset redirects to new errors url and keeps the same query params - if (location.query.dataset === 'errors') { + // errors dataset (or no dataset specified) redirects to errors url and keeps the same query params + if ( + location.query.queryDataset !== SavedQueryDatasets.TRANSACTIONS && + location.query.dataset !== Dataset.TRANSACTIONS + ) { + const discoverPath = location.pathname + .replace('/explore/discover/', '') + .replaceAll('/', ''); const targetPath = makeDiscoverPathname({ - path: '/homepage/', + path: `/${discoverPath}/`, organization, }); return ; } // transactions dataset redirects to traces url as we don't support transactions anymore - return ; + return ; } function renderNoAccess() { diff --git a/static/app/views/navigation/secondary/sections/explore/exploreSecondaryNavigation.tsx b/static/app/views/navigation/secondary/sections/explore/exploreSecondaryNavigation.tsx index 4fa542a4b26a..04731b2ea9fa 100644 --- a/static/app/views/navigation/secondary/sections/explore/exploreSecondaryNavigation.tsx +++ b/static/app/views/navigation/secondary/sections/explore/exploreSecondaryNavigation.tsx @@ -65,10 +65,7 @@ export function ExploreSecondaryNavigation() { - + None: self.create_member(user=self.user, organization=self.org, role="owner", teams=[self.team]) self.login_as(self.user) - self.landing_path = f"/organizations/{self.org.slug}/discover/queries/" - self.result_path = f"/organizations/{self.org.slug}/discover/results/" + self.landing_path = f"/organizations/{self.org.slug}/explore/queries/" + self.result_path = f"/organizations/{self.org.slug}/explore/results/" def wait_until_loaded(self) -> None: self.browser.wait_until_not('[data-test-id="loading-indicator"]') From 1c34048f186bf5fbb6e1986efe949448c21261bc Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Mon, 6 Jul 2026 13:45:09 -0400 Subject: [PATCH 4/4] acceptance grr --- tests/acceptance/test_organization_events_v2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/test_organization_events_v2.py b/tests/acceptance/test_organization_events_v2.py index fa412266d1b1..63bc390372fe 100644 --- a/tests/acceptance/test_organization_events_v2.py +++ b/tests/acceptance/test_organization_events_v2.py @@ -165,8 +165,8 @@ def setUp(self) -> None: self.create_member(user=self.user, organization=self.org, role="owner", teams=[self.team]) self.login_as(self.user) - self.landing_path = f"/organizations/{self.org.slug}/explore/queries/" - self.result_path = f"/organizations/{self.org.slug}/explore/results/" + self.landing_path = f"/organizations/{self.org.slug}/explore/errors/queries/" + self.result_path = f"/organizations/{self.org.slug}/explore/errors/results/" def wait_until_loaded(self) -> None: self.browser.wait_until_not('[data-test-id="loading-indicator"]')