diff --git a/static/app/components/sidebar/index.tsx b/static/app/components/sidebar/index.tsx index d2dae4e2fbef91..886c3ef4ffa582 100644 --- a/static/app/components/sidebar/index.tsx +++ b/static/app/components/sidebar/index.tsx @@ -40,6 +40,7 @@ import {space} from 'sentry/styles/space'; import {Organization} from 'sentry/types'; import {isDemoWalkthrough} from 'sentry/utils/demoMode'; import {getDiscoverLandingUrl} from 'sentry/utils/discover/urls'; +import {isActiveSuperuser} from 'sentry/utils/isActiveSuperuser'; import theme from 'sentry/utils/theme'; import {useLocation} from 'sentry/utils/useLocation'; import useMedia from 'sentry/utils/useMedia'; @@ -115,6 +116,7 @@ function Sidebar({organization}: Props) { const collapsed = !!preferences.collapsed; const horizontal = useMedia(`(max-width: ${theme.breakpoints.medium})`); + const hasSuperuserSession = isActiveSuperuser(organization); useOpenOnboardingSidebar(); @@ -497,7 +499,11 @@ function Sidebar({organization}: Props) { ); return ( - + ` - background: ${p => p.theme.sidebarGradient}; - color: ${p => p.theme.sidebar.color}; +export const SidebarWrapper = styled('nav')<{collapsed: boolean; isSuperuser?: boolean}>` + background: ${p => + p.isSuperuser ? p.theme.superuserSidebar : p.theme.sidebarGradient}; + color: ${p => (p.isSuperuser ? 'white' : p.theme.sidebar.color)}; line-height: 1; padding: 12px 0 2px; /* Allows for 32px avatars */ width: ${p => p.theme.sidebar[p.collapsed ? 'collapsedWidth' : 'expandedWidth']}; diff --git a/static/app/constants/index.tsx b/static/app/constants/index.tsx index 5cce66adb6c0a8..917e004633245d 100644 --- a/static/app/constants/index.tsx +++ b/static/app/constants/index.tsx @@ -54,6 +54,29 @@ export const API_ACCESS_SCOPES = [ 'team:write', ] as const; +export const ALLOWED_SCOPES = [ + 'alerts:read', + 'alerts:write', + 'event:admin', + 'event:read', + 'event:write', + 'member:admin', + 'member:read', + 'member:write', + 'org:admin', + 'org:integrations', + 'org:read', + 'org:superuser', // not an assignable API access scope + 'org:write', + 'project:admin', + 'project:read', + 'project:releases', + 'project:write', + 'team:admin', + 'team:read', + 'team:write', +] as const; + // These should only be used in the case where we cannot obtain roles through // the members endpoint (primarily in cases where a user is admining a // different organization they are not a OrganizationMember of ). diff --git a/static/app/types/core.tsx b/static/app/types/core.tsx index efba874626bad7..e432be3cc27f0e 100644 --- a/static/app/types/core.tsx +++ b/static/app/types/core.tsx @@ -6,7 +6,7 @@ */ import type {getInterval} from 'sentry/components/charts/utils'; import {MenuListItemProps} from 'sentry/components/menuListItem'; -import type {API_ACCESS_SCOPES} from 'sentry/constants'; +import type {ALLOWED_SCOPES} from 'sentry/constants'; /** * Visual representation of a project/team/organization/user @@ -31,7 +31,7 @@ export type Actor = { email?: string; }; -export type Scope = (typeof API_ACCESS_SCOPES)[number]; +export type Scope = (typeof ALLOWED_SCOPES)[number]; export type DateString = Date | string | null; diff --git a/static/app/utils/isActiveSuperuser.tsx b/static/app/utils/isActiveSuperuser.tsx index 6a5321a4c647ce..c14b79391fd8aa 100644 --- a/static/app/utils/isActiveSuperuser.tsx +++ b/static/app/utils/isActiveSuperuser.tsx @@ -1,6 +1,7 @@ import Cookies from 'js-cookie'; import ConfigStore from 'sentry/stores/configStore'; +import {Organization} from 'sentry/types/organization'; const SUPERUSER_COOKIE_NAME = window.superUserCookieName ?? 'su'; const SUPERUSER_COOKIE_DOMAIN = window.superUserCookieDomain; @@ -15,7 +16,11 @@ const SUPERUSER_COOKIE_DOMAIN = window.superUserCookieDomain; * * Documented here: https://getsentry.atlassian.net/browse/ER-1602 */ -export function isActiveSuperuser() { +export function isActiveSuperuser(organization?: Organization) { + if (organization) { + return organization.access.includes('org:superuser'); + } + const {isSuperuser} = ConfigStore.get('user') || {}; if (isSuperuser) { diff --git a/static/app/utils/theme.tsx b/static/app/utils/theme.tsx index 622b1a475f7e8c..b1287df7ba8eae 100644 --- a/static/app/utils/theme.tsx +++ b/static/app/utils/theme.tsx @@ -946,6 +946,7 @@ export const lightTheme = { }, sidebarGradient: `linear-gradient(294.17deg,${sidebarBackground.light} 35.57%,#452650 92.42%,#452650 92.42%)`, sidebarBorder: 'transparent', + superuserSidebar: '#880808', }; export const darkTheme: Theme = { @@ -973,6 +974,7 @@ export const darkTheme: Theme = { }, sidebarGradient: `linear-gradient(180deg, ${sidebarBackground.dark} 0%, #1B1825 100%)`, sidebarBorder: darkAliases.border, + superuserSidebar: '#620808', }; type Theme = typeof lightTheme;