From db37d2395347432e36831e5830e20af607ece5d6 Mon Sep 17 00:00:00 2001 From: Mia Hsu Date: Mon, 11 Aug 2025 09:37:09 -0700 Subject: [PATCH 1/8] feat(aci): redirect to alert rules when UI FF is off --- static/app/views/automations/routes.tsx | 111 +++++++++++++++++++++++- 1 file changed, 110 insertions(+), 1 deletion(-) diff --git a/static/app/views/automations/routes.tsx b/static/app/views/automations/routes.tsx index 97a348517fb5b3..8182eb610661c5 100644 --- a/static/app/views/automations/routes.tsx +++ b/static/app/views/automations/routes.tsx @@ -1,5 +1,12 @@ +import LoadingIndicator from 'sentry/components/loadingIndicator'; +import type {SentryRouteObject} from 'sentry/components/route'; import {makeLazyloadComponent as make} from 'sentry/makeLazyloadComponent'; -import type {SentryRouteObject} from 'sentry/router/types'; +import {useApiQuery} from 'sentry/utils/queryClient'; +import {useNavigate} from 'sentry/utils/useNavigate'; +import useOrganization from 'sentry/utils/useOrganization'; +import {useParams} from 'sentry/utils/useParams'; +import {useUser} from 'sentry/utils/useUser'; +import {makeAlertsPathname} from 'sentry/views/alerts/pathnames'; export const automationRoutes: SentryRouteObject = { path: 'alerts/', @@ -7,9 +14,17 @@ export const automationRoutes: SentryRouteObject = { { index: true, component: make(() => import('sentry/views/automations/list')), + // BROKEN: Results in empty page + // component: RedirectToRuleList, + // deprecatedRouteProps: true, + // children: [ + // {index: true, component: make(() => import('sentry/views/automations/list'))}, + // ], }, { path: 'new', + component: RedirectToNewRule, + deprecatedRouteProps: true, children: [ { index: true, @@ -19,6 +34,8 @@ export const automationRoutes: SentryRouteObject = { }, { path: ':automationId/', + component: RedirectToRuleDetails, + deprecatedRouteProps: true, children: [ { index: true, @@ -32,3 +49,95 @@ export const automationRoutes: SentryRouteObject = { }, ], }; + +function RedirectToRuleList({children}: {children: React.ReactNode}) { + const user = useUser(); + const organization = useOrganization(); + const navigate = useNavigate(); + + const shouldRedirect = + !user.isStaff && !organization.features.includes('workflow-engine-ui'); + + if (shouldRedirect) { + navigate( + makeAlertsPathname({ + path: '/rules/', + organization, + }), + { + replace: true, + } + ); + } + + return children; +} + +export function RedirectToNewRule({children}: {children: React.ReactNode}) { + const user = useUser(); + const organization = useOrganization(); + const navigate = useNavigate(); + + const shouldRedirect = + !user.isStaff && !organization.features.includes('workflow-engine-ui'); + + if (shouldRedirect) { + navigate( + makeAlertsPathname({ + path: '/new/', + organization, + }), + { + replace: true, + } + ); + } + + return children; +} + +interface AlertRuleWorkflow { + workflowId: string; + alertRuleId?: string; + ruleId?: string; +} + +export function RedirectToRuleDetails({children}: {children: React.ReactNode}) { + const user = useUser(); + const organization = useOrganization(); + const navigate = useNavigate(); + + const params = useParams<{automationId: string}>(); + + const shouldRedirect = + !user.isStaff && !organization.features.includes('workflow-engine-ui'); + + const {data} = useApiQuery( + [ + `/organizations/${organization.slug}/alert-rule-workflows/`, + { + query: {workflowId: params.automationId}, + }, + ], + {staleTime: Infinity, retry: false, enabled: shouldRedirect} + ); + + if (shouldRedirect) { + if (!data) { + return ; + } + navigate( + makeAlertsPathname({ + path: data.ruleId + ? `/rules/details/${data.ruleId}/` + : `/rules/details/${data.alertRuleId}/`, + organization, + }), + { + replace: true, + } + ); + } + + return children; +} From e01fff91c67808db1149a21cc3f0874afd146eab Mon Sep 17 00:00:00 2001 From: Mia Hsu Date: Mon, 11 Aug 2025 14:14:03 -0700 Subject: [PATCH 2/8] fix broken index and use Redirect component --- static/app/views/automations/routes.tsx | 63 ++++++++++--------------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/static/app/views/automations/routes.tsx b/static/app/views/automations/routes.tsx index 8182eb610661c5..42ce0ec12651fd 100644 --- a/static/app/views/automations/routes.tsx +++ b/static/app/views/automations/routes.tsx @@ -1,8 +1,8 @@ import LoadingIndicator from 'sentry/components/loadingIndicator'; +import Redirect from 'sentry/components/redirect'; import type {SentryRouteObject} from 'sentry/components/route'; import {makeLazyloadComponent as make} from 'sentry/makeLazyloadComponent'; import {useApiQuery} from 'sentry/utils/queryClient'; -import {useNavigate} from 'sentry/utils/useNavigate'; import useOrganization from 'sentry/utils/useOrganization'; import {useParams} from 'sentry/utils/useParams'; import {useUser} from 'sentry/utils/useUser'; @@ -12,14 +12,11 @@ export const automationRoutes: SentryRouteObject = { path: 'alerts/', children: [ { - index: true, - component: make(() => import('sentry/views/automations/list')), - // BROKEN: Results in empty page - // component: RedirectToRuleList, - // deprecatedRouteProps: true, - // children: [ - // {index: true, component: make(() => import('sentry/views/automations/list'))}, - // ], + component: RedirectToRuleList, + deprecatedRouteProps: true, + children: [ + {index: true, component: make(() => import('sentry/views/automations/list'))}, + ], }, { path: 'new', @@ -53,21 +50,17 @@ export const automationRoutes: SentryRouteObject = { function RedirectToRuleList({children}: {children: React.ReactNode}) { const user = useUser(); const organization = useOrganization(); - const navigate = useNavigate(); const shouldRedirect = !user.isStaff && !organization.features.includes('workflow-engine-ui'); if (shouldRedirect) { - navigate( - makeAlertsPathname({ + ; } return children; @@ -76,20 +69,18 @@ function RedirectToRuleList({children}: {children: React.ReactNode}) { export function RedirectToNewRule({children}: {children: React.ReactNode}) { const user = useUser(); const organization = useOrganization(); - const navigate = useNavigate(); const shouldRedirect = !user.isStaff && !organization.features.includes('workflow-engine-ui'); if (shouldRedirect) { - navigate( - makeAlertsPathname({ - path: '/new/', - organization, - }), - { - replace: true, - } + return ( + ); } @@ -105,7 +96,6 @@ interface AlertRuleWorkflow { export function RedirectToRuleDetails({children}: {children: React.ReactNode}) { const user = useUser(); const organization = useOrganization(); - const navigate = useNavigate(); const params = useParams<{automationId: string}>(); @@ -126,16 +116,15 @@ export function RedirectToRuleDetails({children}: {children: React.ReactNode}) { if (!data) { return ; } - navigate( - makeAlertsPathname({ - path: data.ruleId - ? `/rules/details/${data.ruleId}/` - : `/rules/details/${data.alertRuleId}/`, - organization, - }), - { - replace: true, - } + return ( + ); } From a4269ef82b61d45c1aa2b7e6f5e5b1e113621a93 Mon Sep 17 00:00:00 2001 From: Mia Hsu Date: Mon, 11 Aug 2025 14:17:01 -0700 Subject: [PATCH 3/8] remove useWorkflowEngineFeatureGate --- static/app/views/automations/edit.tsx | 3 --- static/app/views/automations/list.tsx | 3 --- static/app/views/automations/new.tsx | 2 -- 3 files changed, 8 deletions(-) diff --git a/static/app/views/automations/edit.tsx b/static/app/views/automations/edit.tsx index dc49a8d4b28b4a..90e5a87f69225a 100644 --- a/static/app/views/automations/edit.tsx +++ b/static/app/views/automations/edit.tsx @@ -14,7 +14,6 @@ import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; import {FullHeightForm} from 'sentry/components/workflowEngine/form/fullHeightForm'; import {useFormField} from 'sentry/components/workflowEngine/form/useFormField'; import {StickyFooter} from 'sentry/components/workflowEngine/ui/footer'; -import {useWorkflowEngineFeatureGate} from 'sentry/components/workflowEngine/useWorkflowEngineFeatureGate'; import {t} from 'sentry/locale'; import type {Automation, NewAutomation} from 'sentry/types/workflowEngine/automations'; import {DataConditionGroupLogicType} from 'sentry/types/workflowEngine/dataConditions'; @@ -72,8 +71,6 @@ function AutomationBreadcrumbs({automationId}: {automationId: string}) { export default function AutomationEdit() { const params = useParams<{automationId: string}>(); - useWorkflowEngineFeatureGate({redirect: true}); - const { data: automation, isPending, diff --git a/static/app/views/automations/list.tsx b/static/app/views/automations/list.tsx index 0006d4320fc015..e34f05915c6afe 100644 --- a/static/app/views/automations/list.tsx +++ b/static/app/views/automations/list.tsx @@ -6,7 +6,6 @@ import {ProjectPageFilter} from 'sentry/components/organizations/projectPageFilt import Pagination from 'sentry/components/pagination'; import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; import ListLayout from 'sentry/components/workflowEngine/layout/list'; -import {useWorkflowEngineFeatureGate} from 'sentry/components/workflowEngine/useWorkflowEngineFeatureGate'; import {IconAdd} from 'sentry/icons'; import {t} from 'sentry/locale'; import parseLinkHeader from 'sentry/utils/parseLinkHeader'; @@ -25,8 +24,6 @@ import {useAutomationsQuery} from 'sentry/views/automations/hooks'; import {makeAutomationCreatePathname} from 'sentry/views/automations/pathnames'; export default function AutomationsList() { - useWorkflowEngineFeatureGate({redirect: true}); - const location = useLocation(); const navigate = useNavigate(); const {selection, isReady} = usePageFilters(); diff --git a/static/app/views/automations/new.tsx b/static/app/views/automations/new.tsx index b96019d29dd228..ae4ab9b26239be 100644 --- a/static/app/views/automations/new.tsx +++ b/static/app/views/automations/new.tsx @@ -12,7 +12,6 @@ import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; import {FullHeightForm} from 'sentry/components/workflowEngine/form/fullHeightForm'; import {useFormField} from 'sentry/components/workflowEngine/form/useFormField'; import {StickyFooter} from 'sentry/components/workflowEngine/ui/footer'; -import {useWorkflowEngineFeatureGate} from 'sentry/components/workflowEngine/useWorkflowEngineFeatureGate'; import {t} from 'sentry/locale'; import {useLocation} from 'sentry/utils/useLocation'; import {useNavigate} from 'sentry/utils/useNavigate'; @@ -71,7 +70,6 @@ export default function AutomationNewSettings() { const navigate = useNavigate(); const location = useLocation(); const organization = useOrganization(); - useWorkflowEngineFeatureGate({redirect: true}); const model = useMemo(() => new FormModel(), []); const {state, actions} = useAutomationBuilderReducer(); const theme = useTheme(); From f5fc5846c5b617ab7bac6d08b815138d4ec58b6f Mon Sep 17 00:00:00 2001 From: Mia Hsu Date: Mon, 11 Aug 2025 14:17:57 -0700 Subject: [PATCH 4/8] knip --- static/app/views/automations/routes.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/app/views/automations/routes.tsx b/static/app/views/automations/routes.tsx index 42ce0ec12651fd..7a26062ed87563 100644 --- a/static/app/views/automations/routes.tsx +++ b/static/app/views/automations/routes.tsx @@ -66,7 +66,7 @@ function RedirectToRuleList({children}: {children: React.ReactNode}) { return children; } -export function RedirectToNewRule({children}: {children: React.ReactNode}) { +function RedirectToNewRule({children}: {children: React.ReactNode}) { const user = useUser(); const organization = useOrganization(); @@ -93,7 +93,7 @@ interface AlertRuleWorkflow { ruleId?: string; } -export function RedirectToRuleDetails({children}: {children: React.ReactNode}) { +function RedirectToRuleDetails({children}: {children: React.ReactNode}) { const user = useUser(); const organization = useOrganization(); From 98e26d53a0fed658df15f128c939cde60e51ed6d Mon Sep 17 00:00:00 2001 From: Mia Hsu Date: Tue, 11 Nov 2025 16:26:49 -0800 Subject: [PATCH 5/8] fix rebase mistake lol --- static/app/views/automations/detail.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/static/app/views/automations/detail.tsx b/static/app/views/automations/detail.tsx index 4a72a11a596a48..f17317e32dbc11 100644 --- a/static/app/views/automations/detail.tsx +++ b/static/app/views/automations/detail.tsx @@ -18,7 +18,6 @@ import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; import TimeSince from 'sentry/components/timeSince'; import DetailLayout from 'sentry/components/workflowEngine/layout/detail'; import Section from 'sentry/components/workflowEngine/ui/section'; -import {useWorkflowEngineFeatureGate} from 'sentry/components/workflowEngine/useWorkflowEngineFeatureGate'; import {IconEdit} from 'sentry/icons'; import {t, tct} from 'sentry/locale'; import type {Automation} from 'sentry/types/workflowEngine/automations'; @@ -196,7 +195,6 @@ function AutomationDetailLoadingStates({automationId}: {automationId: string}) { } export default function AutomationDetail() { - useWorkflowEngineFeatureGate({redirect: true}); const params = useParams<{automationId: string}>(); const {data: automation, isPending} = useAutomationQuery(params.automationId); From 6e4d4605177411c256753b3bc342f07964cf8147 Mon Sep 17 00:00:00 2001 From: Mia Hsu Date: Tue, 11 Nov 2025 16:31:12 -0800 Subject: [PATCH 6/8] geez this PR is so old --- static/app/views/automations/routes.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/app/views/automations/routes.tsx b/static/app/views/automations/routes.tsx index 7a26062ed87563..cdad139be28416 100644 --- a/static/app/views/automations/routes.tsx +++ b/static/app/views/automations/routes.tsx @@ -1,7 +1,7 @@ import LoadingIndicator from 'sentry/components/loadingIndicator'; import Redirect from 'sentry/components/redirect'; -import type {SentryRouteObject} from 'sentry/components/route'; import {makeLazyloadComponent as make} from 'sentry/makeLazyloadComponent'; +import type {SentryRouteObject} from 'sentry/router/types'; import {useApiQuery} from 'sentry/utils/queryClient'; import useOrganization from 'sentry/utils/useOrganization'; import {useParams} from 'sentry/utils/useParams'; From 729c41c8cf02053b2ac7bb063ad3859929884474 Mon Sep 17 00:00:00 2001 From: Mia Hsu Date: Tue, 11 Nov 2025 16:37:00 -0800 Subject: [PATCH 7/8] better loading/fallback handling --- static/app/views/automations/routes.tsx | 32 +++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/static/app/views/automations/routes.tsx b/static/app/views/automations/routes.tsx index cdad139be28416..51015bdf921312 100644 --- a/static/app/views/automations/routes.tsx +++ b/static/app/views/automations/routes.tsx @@ -102,7 +102,7 @@ function RedirectToRuleDetails({children}: {children: React.ReactNode}) { const shouldRedirect = !user.isStaff && !organization.features.includes('workflow-engine-ui'); - const {data} = useApiQuery( + const {data, isLoading} = useApiQuery( [ `/organizations/${organization.slug}/alert-rule-workflows/`, { @@ -113,19 +113,27 @@ function RedirectToRuleDetails({children}: {children: React.ReactNode}) { ); if (shouldRedirect) { - if (!data) { + if (isLoading) { return ; } - return ( - - ); + if (data) { + return ( + + ); + } + ; } return children; From 7eec73e1da130e789e79ae084008f1283bbce125 Mon Sep 17 00:00:00 2001 From: Mia Hsu Date: Wed, 12 Nov 2025 10:57:21 -0800 Subject: [PATCH 8/8] redirect workflow details to rule list --- static/app/views/automations/routes.tsx | 71 ++++--------------------- 1 file changed, 9 insertions(+), 62 deletions(-) diff --git a/static/app/views/automations/routes.tsx b/static/app/views/automations/routes.tsx index 51015bdf921312..dd00005eebb0b4 100644 --- a/static/app/views/automations/routes.tsx +++ b/static/app/views/automations/routes.tsx @@ -1,10 +1,7 @@ -import LoadingIndicator from 'sentry/components/loadingIndicator'; import Redirect from 'sentry/components/redirect'; import {makeLazyloadComponent as make} from 'sentry/makeLazyloadComponent'; import type {SentryRouteObject} from 'sentry/router/types'; -import {useApiQuery} from 'sentry/utils/queryClient'; import useOrganization from 'sentry/utils/useOrganization'; -import {useParams} from 'sentry/utils/useParams'; import {useUser} from 'sentry/utils/useUser'; import {makeAlertsPathname} from 'sentry/views/alerts/pathnames'; @@ -31,7 +28,7 @@ export const automationRoutes: SentryRouteObject = { }, { path: ':automationId/', - component: RedirectToRuleDetails, + component: RedirectToRuleList, deprecatedRouteProps: true, children: [ { @@ -55,12 +52,14 @@ function RedirectToRuleList({children}: {children: React.ReactNode}) { !user.isStaff && !organization.features.includes('workflow-engine-ui'); if (shouldRedirect) { - ; + return ( + + ); } return children; @@ -86,55 +85,3 @@ function RedirectToNewRule({children}: {children: React.ReactNode}) { return children; } - -interface AlertRuleWorkflow { - workflowId: string; - alertRuleId?: string; - ruleId?: string; -} - -function RedirectToRuleDetails({children}: {children: React.ReactNode}) { - const user = useUser(); - const organization = useOrganization(); - - const params = useParams<{automationId: string}>(); - - const shouldRedirect = - !user.isStaff && !organization.features.includes('workflow-engine-ui'); - - const {data, isLoading} = useApiQuery( - [ - `/organizations/${organization.slug}/alert-rule-workflows/`, - { - query: {workflowId: params.automationId}, - }, - ], - {staleTime: Infinity, retry: false, enabled: shouldRedirect} - ); - - if (shouldRedirect) { - if (isLoading) { - return ; - } - if (data) { - return ( - - ); - } - ; - } - - return children; -}