@ -1,14 +1,23 @@
import { css , cx } from '@emotion/css' ;
import React , { useMemo } from 'react' ;
import React , { useCallback , use Memo } from 'react' ;
import { GrafanaTheme2 } from '@grafana/data' ;
import { useStyles2 } from '@grafana/ui' ;
import {
GrafanaTheme2 ,
addDurationToDate ,
isValidDate ,
isValidDuration ,
parseDuration ,
dateTimeFormat ,
dateTime ,
} from '@grafana/data' ;
import { useStyles2 , Tooltip } from '@grafana/ui' ;
import { CombinedRule } from 'app/types/unified-alerting' ;
import { DEFAULT_PER_PAGE_PAGINATION } from '../../../../../core/constants' ;
import { useHasRuler } from '../../hooks/useHasRuler' ;
import { Annotation } from '../../utils/constants' ;
import { isGrafanaRulerRule , isGrafanaRulerRulePaused } from '../../utils/rules' ;
import { isNullDate } from '../../utils/time' ;
import { DynamicTable , DynamicTableColumnProps , DynamicTableItemProps } from '../DynamicTable' ;
import { DynamicTableWithGuidelines } from '../DynamicTableWithGuidelines' ;
import { ProvisioningBadge } from '../Provisioning' ;
@ -29,6 +38,7 @@ interface Props {
showGuidelines? : boolean ;
showGroupColumn? : boolean ;
showSummaryColumn? : boolean ;
showNextEvaluationColumn? : boolean ;
emptyMessage? : string ;
className? : string ;
}
@ -40,6 +50,7 @@ export const RulesTable = ({
emptyMessage = 'No rules found.' ,
showGroupColumn = false ,
showSummaryColumn = false ,
showNextEvaluationColumn = false ,
} : Props ) = > {
const styles = useStyles2 ( getStyles ) ;
@ -54,7 +65,7 @@ export const RulesTable = ({
} ) ;
} , [ rules ] ) ;
const columns = useColumns ( showSummaryColumn , showGroupColumn ) ;
const columns = useColumns ( showSummaryColumn , showGroupColumn , showNextEvaluationColumn ) ;
if ( ! rules . length ) {
return < div className = { cx ( wrapperClass , styles . emptyMessage ) } > { emptyMessage } < / div > ;
@ -101,9 +112,29 @@ export const getStyles = (theme: GrafanaTheme2) => ({
` ,
} ) ;
function useColumns ( showSummaryColumn : boolean , showGroupColumn : boolean ) {
function useColumns ( showSummaryColumn : boolean , showGroupColumn : boolean , showNextEvaluationColumn : boolean ) {
const { hasRuler , rulerRulesLoaded } = useHasRuler ( ) ;
const calculateNextEvaluationDate = useCallback ( ( rule : CombinedRule ) = > {
const isValidLastEvaluation =
rule . promRule ? . lastEvaluation &&
! isNullDate ( rule . promRule . lastEvaluation ) &&
isValidDate ( rule . promRule . lastEvaluation ) ;
const isValidIntervalDuration = rule . group . interval && isValidDuration ( rule . group . interval ) ;
if ( ! isValidLastEvaluation || ! isValidIntervalDuration ) {
return ;
}
const lastEvaluationDate = Date . parse ( rule . promRule ? . lastEvaluation || '' ) ;
const intervalDuration = parseDuration ( rule . group . interval ! ) ;
const nextEvaluationDate = addDurationToDate ( lastEvaluationDate , intervalDuration ) ;
return {
humanized : dateTime ( nextEvaluationDate ) . locale ( 'en' ) . fromNow ( true ) ,
fullDate : dateTimeFormat ( nextEvaluationDate , { format : 'YYYY-MM-DD HH:mm:ss' } ) ,
} ;
} , [ ] ) ;
return useMemo ( ( ) : RuleTableColumnProps [ ] = > {
const columns : RuleTableColumnProps [ ] = [
{
@ -128,7 +159,7 @@ function useColumns(showSummaryColumn: boolean, showGroupColumn: boolean) {
label : 'Name' ,
// eslint-disable-next-line react/display-name
renderCell : ( { data : rule } ) = > rule . name ,
size : 5 ,
size : showNextEvaluationColumn ? 4 : 5 ,
} ,
{
id : 'provisioned' ,
@ -169,9 +200,28 @@ function useColumns(showSummaryColumn: boolean, showGroupColumn: boolean) {
renderCell : ( { data : rule } ) = > {
return < Tokenize input = { rule . annotations [ Annotation . summary ] ? ? '' } / > ;
} ,
size : 5 ,
size : showNextEvaluationColumn ? 4 : 5 ,
} ) ;
}
if ( showNextEvaluationColumn ) {
columns . push ( {
id : 'nextEvaluation' ,
label : 'Next evaluation' ,
renderCell : ( { data : rule } ) = > {
const nextEvalInfo = calculateNextEvaluationDate ( rule ) ;
return (
nextEvalInfo ? . fullDate && (
< Tooltip placement = "top" content = { ` ${ nextEvalInfo ? . fullDate } ` } theme = "info" >
< span > in { nextEvalInfo ? . humanized } < / span >
< / Tooltip >
)
) ;
} ,
size : 2 ,
} ) ;
}
if ( showGroupColumn ) {
columns . push ( {
id : 'group' ,
@ -203,5 +253,12 @@ function useColumns(showSummaryColumn: boolean, showGroupColumn: boolean) {
} ) ;
return columns ;
} , [ showSummaryColumn , showGroupColumn , hasRuler , rulerRulesLoaded ] ) ;
} , [
showSummaryColumn ,
showGroupColumn ,
showNextEvaluationColumn ,
hasRuler ,
rulerRulesLoaded ,
calculateNextEvaluationDate ,
] ) ;
}