From b6777a6a3fd8bb57063b466ae6a7b9396010cf99 Mon Sep 17 00:00:00 2001 From: JonasBa Date: Thu, 26 Mar 2026 09:42:56 -0700 Subject: [PATCH 1/2] ref(layout): use Layout.Page on alerts --- static/app/views/alerts/create.tsx | 4 +- static/app/views/alerts/edit.tsx | 4 +- .../app/views/alerts/list/incidents/index.tsx | 66 ++--- .../alerts/list/rules/alertRulesList.tsx | 246 +++++++++--------- 4 files changed, 163 insertions(+), 157 deletions(-) diff --git a/static/app/views/alerts/create.tsx b/static/app/views/alerts/create.tsx index 8230782cf304cf..7179f1f4db1bcf 100644 --- a/static/app/views/alerts/create.tsx +++ b/static/app/views/alerts/create.tsx @@ -137,7 +137,7 @@ export default function Create() { const title = t('New Alert Rule'); return ( - + @@ -228,6 +228,6 @@ export default function Create() { )} - + ); } diff --git a/static/app/views/alerts/edit.tsx b/static/app/views/alerts/edit.tsx index 9805c6bbfb5c1c..a5dced1453d396 100644 --- a/static/app/views/alerts/edit.tsx +++ b/static/app/views/alerts/edit.tsx @@ -61,7 +61,7 @@ export default function ProjectAlertsEditor() { const {teams, isLoading: teamsLoading} = useUserTeams(); return ( - + )} - + ); } diff --git a/static/app/views/alerts/list/incidents/index.tsx b/static/app/views/alerts/list/incidents/index.tsx index b3d75f8a7cf9ca..eb2d9e0b008c59 100644 --- a/static/app/views/alerts/list/incidents/index.tsx +++ b/static/app/views/alerts/list/incidents/index.tsx @@ -263,28 +263,30 @@ class IncidentsList extends DeprecatedAsyncComponent< return ( - - - - - {!this.tryRenderOnboarding() && ( - - - {t('This page only shows metric alerts.')} - - - - )} - {this.renderList()} - - - + + + + + + {!this.tryRenderOnboarding() && ( + + + {t('This page only shows metric alerts.')} + + + + )} + {this.renderList()} + + + + ); } @@ -303,15 +305,17 @@ export default function IncidentsListContainer() { }, []); const renderDisabled = () => ( - - - - - {t("You don't have access to this feature")} - - - - + + + + + + {t("You don't have access to this feature")} + + + + + ); return ( diff --git a/static/app/views/alerts/list/rules/alertRulesList.tsx b/static/app/views/alerts/list/rules/alertRulesList.tsx index 1c5e300230d21b..8d37a4e8d81516 100644 --- a/static/app/views/alerts/list/rules/alertRulesList.tsx +++ b/static/app/views/alerts/list/rules/alertRulesList.tsx @@ -210,132 +210,134 @@ export default function AlertRulesList() { - - - - - - {!hasMetricAlertsFeature && hasAnyMetricAlerts && ( - - - Your metric alerts have been disabled. Upgrade your plan to re-enable - them. - - - )} - - - {t('Alert Rule')} {sort.field === 'name' ? sortArrow : null} - , - - {t('Status')} {isAlertRuleSort ? sortArrow : null} - , - t('Project'), - t('Team'), - t('Actions'), - ]} - > - {isError ? ( - - ) : null} - 0} + + + + + + + {!hasMetricAlertsFeature && hasAnyMetricAlerts && ( + + + Your metric alerts have been disabled. Upgrade your plan to re-enable + them. + + + )} + + + {t('Alert Rule')} {sort.field === 'name' ? sortArrow : null} + , + + {t('Status')} {isAlertRuleSort ? sortArrow : null} + , + t('Project'), + t('Team'), + t('Actions'), + ]} > - - {({initiallyLoaded, projects}) => - ruleList.map(rule => { - const isIssueAlertInstance = isIssueAlert(rule); - const keyPrefix = isIssueAlertInstance - ? AlertRuleType.ISSUE - : rule.type === CombinedAlertType.UPTIME - ? AlertRuleType.UPTIME - : AlertRuleType.METRIC; + {isError ? ( + + ) : null} + 0} + > + + {({initiallyLoaded, projects}) => + ruleList.map(rule => { + const isIssueAlertInstance = isIssueAlert(rule); + const keyPrefix = isIssueAlertInstance + ? AlertRuleType.ISSUE + : rule.type === CombinedAlertType.UPTIME + ? AlertRuleType.UPTIME + : AlertRuleType.METRIC; - return ( - - ); - }) + return ( + + ); + }) + } + + + + { + let team = currentQuery.team; + // Keep team parameter, but empty to remove parameters + if (!team || team.length === 0) { + team = ''; } - - - - { - let team = currentQuery.team; - // Keep team parameter, but empty to remove parameters - if (!team || team.length === 0) { - team = ''; - } - navigate({ - pathname: path, - query: {...currentQuery, team, cursor}, - }); - }} - /> - - - + navigate({ + pathname: path, + query: {...currentQuery, team, cursor}, + }); + }} + /> + + + + ); } From 6c03a42f8313e8ea41be0a5f0b999de8b41ec9e2 Mon Sep 17 00:00:00 2001 From: Priscila Oliveira Date: Fri, 27 Mar 2026 11:07:54 +0100 Subject: [PATCH 2/2] ref(layout): use Layout.Page on issue alert details Wrap the issue alert rule details page with Layout.Page, consistent with the other alert pages updated in the prior commit. Co-Authored-By: Claude Opus 4.6 --- .../rules/issue/details/ruleDetails.tsx | 250 +++++++++--------- 1 file changed, 126 insertions(+), 124 deletions(-) diff --git a/static/app/views/alerts/rules/issue/details/ruleDetails.tsx b/static/app/views/alerts/rules/issue/details/ruleDetails.tsx index a32f1eb4f7922a..2040b0d26c7628 100644 --- a/static/app/views/alerts/rules/issue/details/ruleDetails.tsx +++ b/static/app/views/alerts/rules/issue/details/ruleDetails.tsx @@ -383,139 +383,141 @@ export default function AlertRuleDetails() { const {period, start, end, utc} = getDataDatetime(); const cursor = decodeScalar(location.query.cursor); return ( - - - - - - - - + + + + + + - {rule.name} - - - - - - {({hasAccess}) => ( - - )} - - } - to={duplicateLink} - disabled={rule.status === 'disabled'} - > - {t('Duplicate')} - - } - to={makeAlertsPathname({ - path: `/rules/${projectSlug}/${ruleId}/`, - organization, - })} - onClick={() => - trackAnalytics('issue_alert_rule_details.edit_clicked', { + + + {rule.name} + + + + + + {({hasAccess}) => ( + + )} + + } + to={duplicateLink} + disabled={rule.status === 'disabled'} + > + {t('Duplicate')} + + } + to={makeAlertsPathname({ + path: `/rules/${projectSlug}/${ruleId}/`, organization, - rule_id: parseInt(ruleId, 10), - }) - } - > - {rule.status === 'disabled' ? t('Edit to enable') : t('Edit Rule')} - - - - - - - - {renderIncompatibleAlert()} - {renderDisabledAlertBanner()} - {rule.snooze && ( - - {rule.snoozeForEveryone ? ( - - {tct( - "[creator] muted this alert for everyone so you won't get these notifications in the future.", - { - creator: rule.snoozeCreatedBy, - } - )} - - ) : ( - - )} - - )} - - - + trackAnalytics('issue_alert_rule_details.edit_clicked', { + organization, + rule_id: parseInt(ruleId, 10), + }) + } + > + {rule.status === 'disabled' ? t('Edit to enable') : t('Edit Rule')} + + + + + + + + {renderIncompatibleAlert()} + {renderDisabledAlertBanner()} + {rule.snooze && ( + + {rule.snoozeForEveryone ? ( + + {tct( + "[creator] muted this alert for everyone so you won't get these notifications in the future.", + { + creator: rule.snoozeCreatedBy, + } + )} + + ) : ( + + )} + + )} + + + + + - - - - - - - - + + + + + + + ); }