@@ -210,132 +210,134 @@ export default function AlertRulesList() {
210210 < Fragment >
211211 < SentryDocumentTitle title = { t ( 'Alerts' ) } orgSlug = { organization . slug } />
212212
213- < PageFiltersContainer >
214- < AlertHeader activeTab = "rules" />
215- < Layout . Body >
216- < Layout . Main width = "full" >
217- < DataConsentBanner source = "alerts" />
218- { ! hasMetricAlertsFeature && hasAnyMetricAlerts && (
219- < Alert . Container >
220- < Alert variant = "danger" >
221- Your metric alerts have been disabled. Upgrade your plan to re-enable
222- them.
223- </ Alert >
224- </ Alert . Container >
225- ) }
226- < FilterBar
227- location = { location }
228- onChangeFilter = { handleChangeFilter }
229- onChangeSearch = { handleChangeSearch }
230- onChangeAlertType = { handleChangeType }
231- hasTypeFilter
232- />
233- < StyledPanelTable
234- isLoading = { isPending }
235- isEmpty = { ruleList . length === 0 && ! isError }
236- emptyMessage = { t ( 'No alert rules found for the current query.' ) }
237- headers = { [
238- < StyledSortLink
239- key = "name"
240- role = "columnheader"
241- aria-sort = {
242- sort . field === 'name'
243- ? sort . asc
244- ? 'ascending'
245- : 'descending'
246- : 'none'
247- }
248- to = { {
249- pathname : location . pathname ,
250- query : {
251- ...currentQuery ,
252- // sort by name should start by ascending on first click
253- asc : sort . field === 'name' && sort . asc ? undefined : '1' ,
254- sort : 'name' ,
255- } ,
256- } }
257- >
258- { t ( 'Alert Rule' ) } { sort . field === 'name' ? sortArrow : null }
259- </ StyledSortLink > ,
260- < StyledSortLink
261- key = "status"
262- role = "columnheader"
263- aria-sort = {
264- isAlertRuleSort ? ( sort . asc ? 'ascending' : 'descending' ) : 'none'
265- }
266- to = { {
267- pathname : location . pathname ,
268- query : {
269- ...currentQuery ,
270- asc : isAlertRuleSort && ! sort . asc ? '1' : undefined ,
271- sort : [ 'incident_status' , 'date_triggered' ] ,
272- } ,
273- } }
274- >
275- { t ( 'Status' ) } { isAlertRuleSort ? sortArrow : null }
276- </ StyledSortLink > ,
277- t ( 'Project' ) ,
278- t ( 'Team' ) ,
279- t ( 'Actions' ) ,
280- ] }
281- >
282- { isError ? (
283- < StyledLoadingError
284- message = { t ( 'There was an error loading alerts.' ) }
285- onRetry = { refetch }
286- />
287- ) : null }
288- < VisuallyCompleteWithData
289- id = "AlertRules-Body"
290- hasData = { ruleList . length > 0 }
213+ < Layout . Page >
214+ < PageFiltersContainer >
215+ < AlertHeader activeTab = "rules" />
216+ < Layout . Body >
217+ < Layout . Main width = "full" >
218+ < DataConsentBanner source = "alerts" />
219+ { ! hasMetricAlertsFeature && hasAnyMetricAlerts && (
220+ < Alert . Container >
221+ < Alert variant = "danger" >
222+ Your metric alerts have been disabled. Upgrade your plan to re-enable
223+ them.
224+ </ Alert >
225+ </ Alert . Container >
226+ ) }
227+ < FilterBar
228+ location = { location }
229+ onChangeFilter = { handleChangeFilter }
230+ onChangeSearch = { handleChangeSearch }
231+ onChangeAlertType = { handleChangeType }
232+ hasTypeFilter
233+ />
234+ < StyledPanelTable
235+ isLoading = { isPending }
236+ isEmpty = { ruleList . length === 0 && ! isError }
237+ emptyMessage = { t ( 'No alert rules found for the current query.' ) }
238+ headers = { [
239+ < StyledSortLink
240+ key = "name"
241+ role = "columnheader"
242+ aria-sort = {
243+ sort . field === 'name'
244+ ? sort . asc
245+ ? 'ascending'
246+ : 'descending'
247+ : 'none'
248+ }
249+ to = { {
250+ pathname : location . pathname ,
251+ query : {
252+ ...currentQuery ,
253+ // sort by name should start by ascending on first click
254+ asc : sort . field === 'name' && sort . asc ? undefined : '1' ,
255+ sort : 'name' ,
256+ } ,
257+ } }
258+ >
259+ { t ( 'Alert Rule' ) } { sort . field === 'name' ? sortArrow : null }
260+ </ StyledSortLink > ,
261+ < StyledSortLink
262+ key = "status"
263+ role = "columnheader"
264+ aria-sort = {
265+ isAlertRuleSort ? ( sort . asc ? 'ascending' : 'descending' ) : 'none'
266+ }
267+ to = { {
268+ pathname : location . pathname ,
269+ query : {
270+ ...currentQuery ,
271+ asc : isAlertRuleSort && ! sort . asc ? '1' : undefined ,
272+ sort : [ 'incident_status' , 'date_triggered' ] ,
273+ } ,
274+ } }
275+ >
276+ { t ( 'Status' ) } { isAlertRuleSort ? sortArrow : null }
277+ </ StyledSortLink > ,
278+ t ( 'Project' ) ,
279+ t ( 'Team' ) ,
280+ t ( 'Actions' ) ,
281+ ] }
291282 >
292- < Projects orgId = { organization . slug } slugs = { projectsFromResults } >
293- { ( { initiallyLoaded, projects} ) =>
294- ruleList . map ( rule => {
295- const isIssueAlertInstance = isIssueAlert ( rule ) ;
296- const keyPrefix = isIssueAlertInstance
297- ? AlertRuleType . ISSUE
298- : rule . type === CombinedAlertType . UPTIME
299- ? AlertRuleType . UPTIME
300- : AlertRuleType . METRIC ;
283+ { isError ? (
284+ < StyledLoadingError
285+ message = { t ( 'There was an error loading alerts.' ) }
286+ onRetry = { refetch }
287+ />
288+ ) : null }
289+ < VisuallyCompleteWithData
290+ id = "AlertRules-Body"
291+ hasData = { ruleList . length > 0 }
292+ >
293+ < Projects orgId = { organization . slug } slugs = { projectsFromResults } >
294+ { ( { initiallyLoaded, projects} ) =>
295+ ruleList . map ( rule => {
296+ const isIssueAlertInstance = isIssueAlert ( rule ) ;
297+ const keyPrefix = isIssueAlertInstance
298+ ? AlertRuleType . ISSUE
299+ : rule . type === CombinedAlertType . UPTIME
300+ ? AlertRuleType . UPTIME
301+ : AlertRuleType . METRIC ;
301302
302- return (
303- < RuleListRow
304- // Metric and issue alerts can have the same id
305- key = { `${ keyPrefix } -${ rule . id } ` }
306- projectsLoaded = { initiallyLoaded }
307- projects = { projects as Project [ ] }
308- rule = { rule }
309- organization = { organization }
310- onOwnerChange = { handleOwnerChange }
311- onDelete = { handleDeleteRule }
312- hasEditAccess = { hasEditAccess }
313- hasMetricAlerts = { hasMetricAlertsFeature }
314- />
315- ) ;
316- } )
303+ return (
304+ < RuleListRow
305+ // Metric and issue alerts can have the same id
306+ key = { `${ keyPrefix } -${ rule . id } ` }
307+ projectsLoaded = { initiallyLoaded }
308+ projects = { projects as Project [ ] }
309+ rule = { rule }
310+ organization = { organization }
311+ onOwnerChange = { handleOwnerChange }
312+ onDelete = { handleDeleteRule }
313+ hasEditAccess = { hasEditAccess }
314+ hasMetricAlerts = { hasMetricAlertsFeature }
315+ />
316+ ) ;
317+ } )
318+ }
319+ </ Projects >
320+ </ VisuallyCompleteWithData >
321+ </ StyledPanelTable >
322+ < Pagination
323+ pageLinks = { ruleListPageLinks }
324+ onCursor = { ( cursor , path , _direction ) => {
325+ let team = currentQuery . team ;
326+ // Keep team parameter, but empty to remove parameters
327+ if ( ! team || team . length === 0 ) {
328+ team = '' ;
317329 }
318- </ Projects >
319- </ VisuallyCompleteWithData >
320- </ StyledPanelTable >
321- < Pagination
322- pageLinks = { ruleListPageLinks }
323- onCursor = { ( cursor , path , _direction ) => {
324- let team = currentQuery . team ;
325- // Keep team parameter, but empty to remove parameters
326- if ( ! team || team . length === 0 ) {
327- team = '' ;
328- }
329330
330- navigate ( {
331- pathname : path ,
332- query : { ...currentQuery , team, cursor} ,
333- } ) ;
334- } }
335- />
336- </ Layout . Main >
337- </ Layout . Body >
338- </ PageFiltersContainer >
331+ navigate ( {
332+ pathname : path ,
333+ query : { ...currentQuery , team, cursor} ,
334+ } ) ;
335+ } }
336+ />
337+ </ Layout . Main >
338+ </ Layout . Body >
339+ </ PageFiltersContainer >
340+ </ Layout . Page >
339341 </ Fragment >
340342 ) ;
341343}
0 commit comments