diff --git a/static/app/components/createAlertButton.tsx b/static/app/components/createAlertButton.tsx
index d413120e694c86..e811880ea22278 100644
--- a/static/app/components/createAlertButton.tsx
+++ b/static/app/components/createAlertButton.tsx
@@ -18,6 +18,7 @@ import type EventView from 'sentry/utils/discover/eventView';
import useApi from 'sentry/utils/useApi';
import useProjects from 'sentry/utils/useProjects';
import useRouter from 'sentry/utils/useRouter';
+import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
import type {AlertType, AlertWizardAlertNames} from 'sentry/views/alerts/wizard/options';
import {
AlertWizardRuleTemplates,
@@ -75,7 +76,10 @@ function CreateAlertFromViewButton({
: DEFAULT_WIZARD_TEMPLATE;
const to = {
- pathname: `/organizations/${organization.slug}/alerts/new/metric/`,
+ pathname: makeAlertsPathname({
+ path: '/new/metric/',
+ organization,
+ }),
query: {
...queryParams,
createFromDiscover: true,
@@ -143,7 +147,12 @@ export default function CreateAlertButton({
if (alertOption) {
params.append('alert_option', alertOption);
}
- return `/organizations/${organization.slug}/alerts/wizard/?${params.toString()}`;
+ return (
+ makeAlertsPathname({
+ path: '/wizard/',
+ organization,
+ }) + `?${params.toString()}`
+ );
};
function handleClickWithoutProject(event: React.MouseEvent) {
diff --git a/static/app/components/events/interfaces/crons/cronTimelineSection.tsx b/static/app/components/events/interfaces/crons/cronTimelineSection.tsx
index c9ea45e6b49257..76416400e23ab1 100644
--- a/static/app/components/events/interfaces/crons/cronTimelineSection.tsx
+++ b/static/app/components/events/interfaces/crons/cronTimelineSection.tsx
@@ -23,6 +23,7 @@ import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {useDimensions} from 'sentry/utils/useDimensions';
import {useLocation} from 'sentry/utils/useLocation';
+import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
import {SectionKey} from 'sentry/views/issueDetails/streamline/context';
import {InterimSection} from 'sentry/views/issueDetails/streamline/interimSection';
import {ResolutionSelector} from 'sentry/views/monitors/components/overviewTimeline/resolutionSelector';
@@ -77,7 +78,10 @@ export function CronTimelineSection({event, organization, project}: Props) {
size="xs"
icon={}
to={{
- pathname: `/organizations/${organization.slug}/alerts/rules/crons/${project.slug}/${monitorSlug}/details/`,
+ pathname: makeAlertsPathname({
+ path: `/rules/crons/${project.slug}/${monitorSlug}/details/`,
+ organization,
+ }),
query: {environment},
}}
>
diff --git a/static/app/components/events/interfaces/uptime/uptimeDataSection.tsx b/static/app/components/events/interfaces/uptime/uptimeDataSection.tsx
index 67bdded595cec2..a3a275cb305114 100644
--- a/static/app/components/events/interfaces/uptime/uptimeDataSection.tsx
+++ b/static/app/components/events/interfaces/uptime/uptimeDataSection.tsx
@@ -25,11 +25,11 @@ import type {Event} from 'sentry/types/event';
import {type Group, GroupActivityType, GroupStatus} from 'sentry/types/group';
import type {Project} from 'sentry/types/project';
import {defined} from 'sentry/utils';
-import normalizeUrl from 'sentry/utils/url/normalizeUrl';
import {useDebouncedValue} from 'sentry/utils/useDebouncedValue';
import {useDimensions} from 'sentry/utils/useDimensions';
import {useLocation} from 'sentry/utils/useLocation';
import useOrganization from 'sentry/utils/useOrganization';
+import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
import {
checkStatusPrecedent,
statusToText,
@@ -133,9 +133,10 @@ export function UptimeDataSection({group, event, project}: Props) {
}
size="xs"
- to={normalizeUrl(
- `/organizations/${organization.slug}/alerts/rules/uptime/${project.slug}/${alertRuleId}/details/`
- )}
+ to={makeAlertsPathname({
+ path: `/rules/uptime/${project.slug}/${alertRuleId}/details/`,
+ organization,
+ })}
>
{t('Uptime Alert Rule')}
diff --git a/static/app/components/onboardingWizard/taskConfig.tsx b/static/app/components/onboardingWizard/taskConfig.tsx
index d616b765529dee..5336c654581c1c 100644
--- a/static/app/components/onboardingWizard/taskConfig.tsx
+++ b/static/app/components/onboardingWizard/taskConfig.tsx
@@ -22,6 +22,7 @@ import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {isDemoModeEnabled} from 'sentry/utils/demoMode';
import {getDemoWalkthroughTasks} from 'sentry/utils/demoMode/guides';
+import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
import {getPerformanceBaseUrl} from 'sentry/views/performance/utils';
import {makeReplaysPathname} from 'sentry/views/replays/pathnames';
@@ -47,12 +48,18 @@ type Options = {
function getIssueAlertUrl({projects, organization}: Options) {
if (!projects || !projects.length) {
- return `/organizations/${organization.slug}/alerts/rules/`;
+ return makeAlertsPathname({
+ path: '/rules/',
+ organization,
+ });
}
// pick the first project with events if we have that, otherwise just pick the first project
const firstProjectWithEvents = projects.find(project => !!project.firstEvent);
const project = firstProjectWithEvents ?? projects[0]!;
- return `/organizations/${organization.slug}/alerts/${project.slug}/wizard/`;
+ return makeAlertsPathname({
+ path: `/${project.slug}/wizard/`,
+ organization,
+ });
}
function getOnboardingInstructionsUrl({projects, organization}: Options) {
diff --git a/static/app/components/sidebar/index.tsx b/static/app/components/sidebar/index.tsx
index 7b9d40d23be03a..abd41b0041ec29 100644
--- a/static/app/components/sidebar/index.tsx
+++ b/static/app/components/sidebar/index.tsx
@@ -55,6 +55,7 @@ import useMedia from 'sentry/utils/useMedia';
import useOrganization from 'sentry/utils/useOrganization';
import usePageFilters from 'sentry/utils/usePageFilters';
import useProjects from 'sentry/utils/useProjects';
+import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
import {MODULE_BASE_URLS} from 'sentry/views/insights/common/utils/useModuleURL';
import {
AI_LANDING_SUB_PATH,
@@ -328,7 +329,10 @@ function Sidebar() {
{...sidebarItemProps}
icon={}
label={t('Alerts')}
- to={`/organizations/${organization.slug}/alerts/rules/`}
+ to={makeAlertsPathname({
+ path: '/rules/',
+ organization,
+ })}
id="alerts"
/>
);
diff --git a/static/app/views/alerts/pathnames.tsx b/static/app/views/alerts/pathnames.tsx
new file mode 100644
index 00000000000000..e5aa7afd3d50dd
--- /dev/null
+++ b/static/app/views/alerts/pathnames.tsx
@@ -0,0 +1,19 @@
+import type {Organization} from 'sentry/types/organization';
+import normalizeUrl from 'sentry/utils/url/normalizeUrl';
+
+const LEGACY_ALERTS_BASE_PATHNAME = 'alerts';
+const ALERTS_BASE_PATHNAME = 'issues/alerts';
+
+export function makeAlertsPathname({
+ path,
+ organization,
+}: {
+ organization: Organization;
+ path: '/' | `/${string}/`;
+}) {
+ return normalizeUrl(
+ organization.features.includes('navigation-sidebar-v2')
+ ? `/organizations/${organization.slug}/${ALERTS_BASE_PATHNAME}${path}`
+ : `/organizations/${organization.slug}/${LEGACY_ALERTS_BASE_PATHNAME}${path}`
+ );
+}
diff --git a/static/app/views/issueDetails/streamline/sidebar/detectorSection.tsx b/static/app/views/issueDetails/streamline/sidebar/detectorSection.tsx
index 5976441a014c16..f6e57e60197242 100644
--- a/static/app/views/issueDetails/streamline/sidebar/detectorSection.tsx
+++ b/static/app/views/issueDetails/streamline/sidebar/detectorSection.tsx
@@ -8,6 +8,7 @@ import type {Group} from 'sentry/types/group';
import type {Organization} from 'sentry/types/organization';
import type {Project} from 'sentry/types/project';
import {getConfigForIssueType} from 'sentry/utils/issueTypeConfig';
+import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
import {useIssueDetails} from 'sentry/views/issueDetails/streamline/context';
import {SidebarSectionTitle} from 'sentry/views/issueDetails/streamline/sidebar/sidebar';
@@ -38,7 +39,10 @@ export function getDetectorDetails({
return {
detectorType: 'metric_alert',
detectorId: metricAlertRuleId,
- detectorPath: `/organizations/${organization.slug}/alerts/rules/details/${metricAlertRuleId}/`,
+ detectorPath: makeAlertsPathname({
+ path: `/rules/details/${metricAlertRuleId}/`,
+ organization,
+ }),
// TODO(issues): We can probably enrich this description with details from the alert itself.
description: t(
'This issue was created by a metric alert detector. View the detector details to learn more.'
@@ -53,7 +57,10 @@ export function getDetectorDetails({
detectorType: 'cron_monitor',
detectorId: cronId,
detectorSlug: cronSlug,
- detectorPath: `/organizations/${organization.slug}/alerts/rules/crons/${project.slug}/${cronSlug}/details/`,
+ detectorPath: makeAlertsPathname({
+ path: `/rules/crons/${project.slug}/${cronSlug}/details/`,
+ organization,
+ }),
description: t(
'This issue was created by a cron monitor. View the monitor details to learn more.'
),
@@ -65,7 +72,10 @@ export function getDetectorDetails({
return {
detectorType: 'uptime_monitor',
detectorId: uptimeAlertRuleId,
- detectorPath: `/organizations/${organization.slug}/alerts/rules/uptime/${project.slug}/${uptimeAlertRuleId}/details/`,
+ detectorPath: makeAlertsPathname({
+ path: `/rules/uptime/${project.slug}/${uptimeAlertRuleId}/details/`,
+ organization,
+ }),
// TODO(issues): Update this to mention detectors when that language is user-facing
description: t(
'This issue was created by an uptime monitoring alert rule after detecting 3 consecutive failed checks.'
diff --git a/static/app/views/organizationStats/teamInsights/teamAlertsTriggered.tsx b/static/app/views/organizationStats/teamInsights/teamAlertsTriggered.tsx
index 7f228d1a5d86bb..43ec651eb31f43 100644
--- a/static/app/views/organizationStats/teamInsights/teamAlertsTriggered.tsx
+++ b/static/app/views/organizationStats/teamInsights/teamAlertsTriggered.tsx
@@ -19,6 +19,7 @@ import type {Project} from 'sentry/types/project';
import {formatPercentage} from 'sentry/utils/number/formatPercentage';
import {useApiQuery} from 'sentry/utils/queryClient';
import type {ColorOrAlias} from 'sentry/utils/theme';
+import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
import type {MetricRule} from 'sentry/views/alerts/rules/metric/types';
import {ProjectBadge, ProjectBadgeContainer} from './styles';
@@ -154,7 +155,10 @@ function TeamAlertsTriggered({
{t('Create Alert')}
@@ -182,7 +186,10 @@ function TeamAlertsTriggered({
{rule.name}
diff --git a/static/app/views/projectDetail/projectLatestAlerts.tsx b/static/app/views/projectDetail/projectLatestAlerts.tsx
index 3788fe369660bd..dcd15a2c1d7c10 100644
--- a/static/app/views/projectDetail/projectLatestAlerts.tsx
+++ b/static/app/views/projectDetail/projectLatestAlerts.tsx
@@ -15,6 +15,8 @@ import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import type {Organization} from 'sentry/types/organization';
import {useApiQuery} from 'sentry/utils/queryClient';
+import useOrganization from 'sentry/utils/useOrganization';
+import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
import type {Incident} from 'sentry/views/alerts/types';
import {IncidentStatus} from 'sentry/views/alerts/types';
@@ -25,10 +27,10 @@ const PLACEHOLDER_AND_EMPTY_HEIGHT = '172px';
interface AlertRowProps {
alert: Incident;
- orgSlug: string;
}
-function AlertRow({alert, orgSlug}: AlertRowProps) {
+function AlertRow({alert}: AlertRowProps) {
+ const organization = useOrganization();
const {status, identifier, title, dateClosed, dateStarted} = alert;
const isResolved = status === IncidentStatus.CLOSED;
const isWarning = status === IncidentStatus.WARNING;
@@ -40,7 +42,10 @@ function AlertRow({alert, orgSlug}: AlertRowProps) {
return (
@@ -154,9 +159,7 @@ function ProjectLatestAlerts({
return alertsUnresolvedAndResolved
.slice(0, 3)
- .map(alert => (
-
- ));
+ .map(alert => );
}
return (
@@ -166,7 +169,10 @@ function ProjectLatestAlerts({
{/* as this is a link to latest alerts, we want to only preserve project and environment */}
{t('Add Alert Rule')}
diff --git a/static/app/views/settings/projectAlerts/settings.tsx b/static/app/views/settings/projectAlerts/settings.tsx
index e6d0816e12584f..be02595a3e0db8 100644
--- a/static/app/views/settings/projectAlerts/settings.tsx
+++ b/static/app/views/settings/projectAlerts/settings.tsx
@@ -19,6 +19,7 @@ import type {ApiQueryKey} from 'sentry/utils/queryClient';
import {setApiQueryData, useApiQuery, useQueryClient} from 'sentry/utils/queryClient';
import routeTitleGen from 'sentry/utils/routeTitle';
import useOrganization from 'sentry/utils/useOrganization';
+import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
import {ProjectPermissionAlert} from 'sentry/views/settings/project/projectPermissionAlert';
@@ -107,7 +108,10 @@ function ProjectAlertSettings({canEditRule, params}: ProjectAlertSettingsProps)
action={