-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
feat(aci): redirect alerts nav to monitors #103325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import {parseAsBoolean, useQueryState} from 'nuqs'; | ||
|
|
||
| import {Alert} from '@sentry/scraps/alert'; | ||
| import {Button} from '@sentry/scraps/button'; | ||
|
|
||
| import {IconClose} from 'sentry/icons'; | ||
| import {t} from 'sentry/locale'; | ||
|
|
||
| export function AlertsRedirectNotice({children}: {children: React.ReactNode}) { | ||
| const [wasRedirectedFromAlerts, setWasRedirectedFromAlerts] = useQueryState( | ||
| 'alertsRedirect', | ||
| parseAsBoolean.withOptions({history: 'replace'}).withDefault(false) | ||
| ); | ||
|
|
||
| if (!wasRedirectedFromAlerts) { | ||
| return null; | ||
| } | ||
|
|
||
| return ( | ||
| <Alert | ||
| type="info" | ||
| trailingItems={ | ||
| <Button | ||
| size="zero" | ||
| borderless | ||
| icon={<IconClose />} | ||
| aria-label={t('Dismiss')} | ||
| onClick={() => { | ||
| setWasRedirectedFromAlerts(false); | ||
| }} | ||
| /> | ||
| } | ||
| > | ||
| {children} | ||
| </Alert> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,8 @@ import styled from '@emotion/styled'; | |
|
|
||
| import {t} from 'sentry/locale'; | ||
| import useOrganization from 'sentry/utils/useOrganization'; | ||
| import {useUser} from 'sentry/utils/useUser'; | ||
| import {makeMonitorBasePathname} from 'sentry/views/detectors/pathnames'; | ||
| import {ISSUE_TAXONOMY_CONFIG} from 'sentry/views/issueList/taxonomies'; | ||
| import {useNavContext} from 'sentry/views/nav/context'; | ||
| import {PRIMARY_NAV_GROUP_CONFIG} from 'sentry/views/nav/primary/config'; | ||
|
|
@@ -81,9 +83,18 @@ export function IssuesSecondaryNav() { | |
| } | ||
|
|
||
| function ConfigureSection({baseUrl}: {baseUrl: string}) { | ||
| const user = useUser(); | ||
| const organization = useOrganization(); | ||
| const {layout} = useNavContext(); | ||
| const isSticky = layout === NavLayout.SIDEBAR; | ||
|
|
||
| const shouldRedirectToWorkflowEngineUI = | ||
| !user.isStaff && organization.features.includes('workflow-engine-ui'); | ||
|
|
||
| const alertsLink = shouldRedirectToWorkflowEngineUI | ||
| ? `${makeMonitorBasePathname(organization.slug)}?alertsRedirect=true` | ||
| : `${baseUrl}/alerts/rules/`; | ||
|
|
||
| return ( | ||
| <StickyBottomSection | ||
| id="issues-configure" | ||
|
|
@@ -92,8 +103,8 @@ function ConfigureSection({baseUrl}: {baseUrl: string}) { | |
| isSticky={isSticky} | ||
| > | ||
| <SecondaryNav.Item | ||
| to={`${baseUrl}/alerts/rules/`} | ||
| activeTo={`${baseUrl}/alerts/`} | ||
| to={alertsLink} | ||
| activeTo={alertsLink} | ||
|
||
| analyticsItemName="issues_alerts" | ||
| > | ||
| {t('Alerts')} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug:
useUser()can returnnull/undefined, butuser.isStaffis accessed without a null check, causing aTypeError.Severity: CRITICAL | Confidence: 0.95
🔍 Detailed Analysis
The
useUser()hook can returnnullorundefineddespite itsReadonly<User>type annotation, as evidenced by explicit type casting and defensive checks in other parts of the codebase. TheissuesSecondaryNav.tsxcomponent directly accessesuser.isStaffwithout a null/undefined check, leading to aTypeError: Cannot read property 'isStaff' of null/undefinedifuseris not yet initialized or becomesnull/undefinedduring early app lifecycle or race conditions.💡 Suggested Fix
Add a null/undefined check for the
userobject before accessinguser.isStaff. For example,if (user && !user.isStaff && organization.features.includes('workflow-engine-ui')).🤖 Prompt for AI Agent
Did we get this right? 👍 / 👎 to inform future reviews.
Reference_id: 2663962