@@ -4,11 +4,13 @@ import * as qs from 'query-string';
4
4
5
5
import { openBulkEditMonitorsModal } from 'sentry/actionCreators/modal' ;
6
6
import { deleteProjectProcessingErrorByType } from 'sentry/actionCreators/monitors' ;
7
+ import { hasEveryAccess } from 'sentry/components/acl/access' ;
7
8
import { Button } from 'sentry/components/button' ;
8
9
import ButtonBar from 'sentry/components/buttonBar' ;
9
10
import FeedbackWidgetButton from 'sentry/components/feedback/widget/feedbackWidgetButton' ;
10
11
import HookOrDefault from 'sentry/components/hookOrDefault' ;
11
12
import * as Layout from 'sentry/components/layouts/thirds' ;
13
+ import Link from 'sentry/components/links/link' ;
12
14
import LoadingIndicator from 'sentry/components/loadingIndicator' ;
13
15
import { DatePageFilter } from 'sentry/components/organizations/datePageFilter' ;
14
16
import { EnvironmentPageFilter } from 'sentry/components/organizations/environmentPageFilter' ;
@@ -20,7 +22,7 @@ import Pagination from 'sentry/components/pagination';
20
22
import SearchBar from 'sentry/components/searchBar' ;
21
23
import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle' ;
22
24
import { IconAdd , IconList } from 'sentry/icons' ;
23
- import { t } from 'sentry/locale' ;
25
+ import { t , tct } from 'sentry/locale' ;
24
26
import { space } from 'sentry/styles/space' ;
25
27
import { useApiQuery } from 'sentry/utils/queryClient' ;
26
28
import { decodeList , decodeScalar } from 'sentry/utils/queryString' ;
@@ -30,6 +32,7 @@ import useApi from 'sentry/utils/useApi';
30
32
import { useLocation } from 'sentry/utils/useLocation' ;
31
33
import { useNavigate } from 'sentry/utils/useNavigate' ;
32
34
import useOrganization from 'sentry/utils/useOrganization' ;
35
+ import useProjects from 'sentry/utils/useProjects' ;
33
36
34
37
import {
35
38
CronsLandingPanel ,
@@ -56,6 +59,7 @@ export default function Monitors() {
56
59
const platform = decodeScalar ( location . query ?. platform ) ?? null ;
57
60
const guide = decodeScalar ( location . query ?. guide ) ;
58
61
const project = decodeList ( location . query ?. project ) ;
62
+ const { projects} = useProjects ( ) ;
59
63
60
64
const queryKey = makeMonitorListQueryKey ( organization , location . query ) ;
61
65
@@ -95,6 +99,14 @@ export default function Monitors() {
95
99
96
100
const showAddMonitor = ! isValidPlatform ( platform ) || ! isValidGuide ( guide ) ;
97
101
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
+
98
110
return (
99
111
< SentryDocumentTitle title = { t ( `Crons` ) } orgSlug = { organization . slug } >
100
112
< CronsListPageHeader organization = { organization } />
@@ -124,11 +136,18 @@ export default function Monitors() {
124
136
}
125
137
analyticsEventKey = "crons.bulk_edit_modal_button_clicked"
126
138
analyticsEventName = "Crons: Bulk Edit Modal Button Clicked"
139
+ disabled = { ! canCreateAlert }
140
+ title = { ! canCreateAlert ? permissionTooltipText : undefined }
127
141
>
128
142
{ t ( 'Manage Monitors' ) }
129
143
</ Button >
130
144
{ 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
+ >
132
151
{ t ( 'Add Monitor' ) }
133
152
</ NewMonitorButton >
134
153
) }
0 commit comments