Skip to content

Commit 3172edc

Browse files
feat(alerts): Restrict uptime/crons overview buttons for alerts:write (#86436)
Follow up to #86318
1 parent f335456 commit 3172edc

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

static/app/views/insights/uptime/views/overview.tsx

+15-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import {Fragment} from 'react';
22
import styled from '@emotion/styled';
33
import * as qs from 'query-string';
44

5+
import {hasEveryAccess} from 'sentry/components/acl/access';
56
import {LinkButton} from 'sentry/components/button';
67
import ButtonBar from 'sentry/components/buttonBar';
78
import EmptyMessage from 'sentry/components/emptyMessage';
89
import * as Layout from 'sentry/components/layouts/thirds';
10+
import Link from 'sentry/components/links/link';
911
import LoadingIndicator from 'sentry/components/loadingIndicator';
1012
import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
1113
import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
@@ -17,7 +19,7 @@ import Pagination from 'sentry/components/pagination';
1719
import Panel from 'sentry/components/panels/panel';
1820
import SearchBar from 'sentry/components/searchBar';
1921
import {IconAdd} from 'sentry/icons';
20-
import {t} from 'sentry/locale';
22+
import {t, tct} from 'sentry/locale';
2123
import {space} from 'sentry/styles/space';
2224
import {useApiQuery} from 'sentry/utils/queryClient';
2325
import {decodeList, decodeScalar} from 'sentry/utils/queryString';
@@ -26,6 +28,7 @@ import useRouteAnalyticsParams from 'sentry/utils/routeAnalytics/useRouteAnalyti
2628
import {useLocation} from 'sentry/utils/useLocation';
2729
import {useNavigate} from 'sentry/utils/useNavigate';
2830
import useOrganization from 'sentry/utils/useOrganization';
31+
import useProjects from 'sentry/utils/useProjects';
2932
import {makeAlertsPathname} from 'sentry/views/alerts/pathnames';
3033
import type {UptimeRule} from 'sentry/views/alerts/rules/uptime/types';
3134
import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders';
@@ -41,6 +44,7 @@ export default function UptimeOverview() {
4144
const navigate = useNavigate();
4245
const location = useLocation();
4346
const project = decodeList(location.query?.project);
47+
const {projects} = useProjects();
4448

4549
function makeQueryKey() {
4650
const {query, environment, owner, cursor, sort, asc} = location.query;
@@ -81,6 +85,14 @@ export default function UptimeOverview() {
8185
});
8286
};
8387

88+
const canCreateAlert =
89+
hasEveryAccess(['alerts:write'], {organization}) ||
90+
projects.some(p => hasEveryAccess(['alerts:write'], {project: p}));
91+
const permissionTooltipText = tct(
92+
'Ask your organization owner or manager to [settingsLink:enable alerts access] for you.',
93+
{settingsLink: <Link to={`/settings/${organization.slug}`} />}
94+
);
95+
8496
return (
8597
<ModulePageProviders moduleName="uptime" pageTitle={t('Overview')}>
8698
<BackendHeader
@@ -104,6 +116,8 @@ export default function UptimeOverview() {
104116
organization,
105117
})}
106118
icon={<IconAdd isCircled />}
119+
disabled={!canCreateAlert}
120+
title={!canCreateAlert ? permissionTooltipText : undefined}
107121
>
108122
{t('Add Uptime Monitor')}
109123
</LinkButton>

static/app/views/monitors/components/overviewTimeline/overviewRow.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {css} from '@emotion/react';
33
import styled from '@emotion/styled';
44
import pick from 'lodash/pick';
55

6+
import {hasEveryAccess} from 'sentry/components/acl/access';
67
import {Button} from 'sentry/components/button';
78
import {CheckInPlaceholder} from 'sentry/components/checkInTimeline/checkInPlaceholder';
89
import {CheckInTimeline} from 'sentry/components/checkInTimeline/checkInTimeline';
@@ -92,6 +93,15 @@ export function OverviewRow({
9293
query,
9394
};
9495

96+
const canDisable = hasEveryAccess(['alerts:write'], {
97+
organization,
98+
project: monitor.project,
99+
});
100+
const permissionTooltipText = tct(
101+
'Ask your organization owner or manager to [settingsLink:enable alerts access] for you.',
102+
{settingsLink: <Link to={`/settings/${organization.slug}`} />}
103+
);
104+
95105
const monitorDetails = singleMonitorView ? null : (
96106
<DetailsArea>
97107
<DetailsLink to={to}>
@@ -126,6 +136,8 @@ export function OverviewRow({
126136
monitor={monitor}
127137
size="xs"
128138
onToggleStatus={status => onToggleStatus(monitor, status)}
139+
disabled={!canDisable}
140+
title={!canDisable ? permissionTooltipText : undefined}
129141
/>
130142
)}
131143
</DetailsActions>

static/app/views/monitors/overview.tsx

+21-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import * as qs from 'query-string';
44

55
import {openBulkEditMonitorsModal} from 'sentry/actionCreators/modal';
66
import {deleteProjectProcessingErrorByType} from 'sentry/actionCreators/monitors';
7+
import {hasEveryAccess} from 'sentry/components/acl/access';
78
import {Button} from 'sentry/components/button';
89
import ButtonBar from 'sentry/components/buttonBar';
910
import FeedbackWidgetButton from 'sentry/components/feedback/widget/feedbackWidgetButton';
1011
import HookOrDefault from 'sentry/components/hookOrDefault';
1112
import * as Layout from 'sentry/components/layouts/thirds';
13+
import Link from 'sentry/components/links/link';
1214
import LoadingIndicator from 'sentry/components/loadingIndicator';
1315
import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
1416
import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
@@ -20,7 +22,7 @@ import Pagination from 'sentry/components/pagination';
2022
import SearchBar from 'sentry/components/searchBar';
2123
import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
2224
import {IconAdd, IconList} from 'sentry/icons';
23-
import {t} from 'sentry/locale';
25+
import {t, tct} from 'sentry/locale';
2426
import {space} from 'sentry/styles/space';
2527
import {useApiQuery} from 'sentry/utils/queryClient';
2628
import {decodeList, decodeScalar} from 'sentry/utils/queryString';
@@ -30,6 +32,7 @@ import useApi from 'sentry/utils/useApi';
3032
import {useLocation} from 'sentry/utils/useLocation';
3133
import {useNavigate} from 'sentry/utils/useNavigate';
3234
import useOrganization from 'sentry/utils/useOrganization';
35+
import useProjects from 'sentry/utils/useProjects';
3336

3437
import {
3538
CronsLandingPanel,
@@ -56,6 +59,7 @@ export default function Monitors() {
5659
const platform = decodeScalar(location.query?.platform) ?? null;
5760
const guide = decodeScalar(location.query?.guide);
5861
const project = decodeList(location.query?.project);
62+
const {projects} = useProjects();
5963

6064
const queryKey = makeMonitorListQueryKey(organization, location.query);
6165

@@ -95,6 +99,14 @@ export default function Monitors() {
9599

96100
const showAddMonitor = !isValidPlatform(platform) || !isValidGuide(guide);
97101

102+
const canCreateAlert =
103+
hasEveryAccess(['alerts:write'], {organization}) ||
104+
projects.some(p => hasEveryAccess(['alerts:write'], {project: p}));
105+
const permissionTooltipText = tct(
106+
'Ask your organization owner or manager to [settingsLink:enable alerts access] for you.',
107+
{settingsLink: <Link to={`/settings/${organization.slug}`} />}
108+
);
109+
98110
return (
99111
<SentryDocumentTitle title={t(`Crons`)} orgSlug={organization.slug}>
100112
<CronsListPageHeader organization={organization} />
@@ -124,11 +136,18 @@ export default function Monitors() {
124136
}
125137
analyticsEventKey="crons.bulk_edit_modal_button_clicked"
126138
analyticsEventName="Crons: Bulk Edit Modal Button Clicked"
139+
disabled={!canCreateAlert}
140+
title={!canCreateAlert ? permissionTooltipText : undefined}
127141
>
128142
{t('Manage Monitors')}
129143
</Button>
130144
{showAddMonitor && (
131-
<NewMonitorButton size="sm" icon={<IconAdd isCircled />}>
145+
<NewMonitorButton
146+
size="sm"
147+
icon={<IconAdd isCircled />}
148+
disabled={!canCreateAlert}
149+
title={!canCreateAlert ? permissionTooltipText : undefined}
150+
>
132151
{t('Add Monitor')}
133152
</NewMonitorButton>
134153
)}

0 commit comments

Comments
 (0)