Alerting: Improve showing nextEvaluationDate for rules (#65205)

* Improve showing nextEvaluationDate for rules

Co-Authored-By: Konrad Lalik <konradlalik@gmail.com>

* Improve imports and comments

---------

Co-authored-by: Konrad Lalik <konradlalik@gmail.com>
pull/65220/head
Virginia Cepeda 2 years ago committed by GitHub
parent ccd1815819
commit b90aed4fd7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 29
      public/app/features/alerting/unified/components/rules/RulesTable.tsx

@ -1,4 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import { isBefore, formatDuration } from 'date-fns';
import React, { useCallback, useMemo } from 'react'; import React, { useCallback, useMemo } from 'react';
import { import {
@ -17,7 +18,6 @@ import { DEFAULT_PER_PAGE_PAGINATION } from '../../../../../core/constants';
import { useHasRuler } from '../../hooks/useHasRuler'; import { useHasRuler } from '../../hooks/useHasRuler';
import { Annotation } from '../../utils/constants'; import { Annotation } from '../../utils/constants';
import { isGrafanaRulerRule, isGrafanaRulerRulePaused } from '../../utils/rules'; import { isGrafanaRulerRule, isGrafanaRulerRulePaused } from '../../utils/rules';
import { isNullDate } from '../../utils/time';
import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable';
import { DynamicTableWithGuidelines } from '../DynamicTableWithGuidelines'; import { DynamicTableWithGuidelines } from '../DynamicTableWithGuidelines';
import { ProvisioningBadge } from '../Provisioning'; import { ProvisioningBadge } from '../Provisioning';
@ -116,21 +116,30 @@ function useColumns(showSummaryColumn: boolean, showGroupColumn: boolean, showNe
const { hasRuler, rulerRulesLoaded } = useHasRuler(); const { hasRuler, rulerRulesLoaded } = useHasRuler();
const calculateNextEvaluationDate = useCallback((rule: CombinedRule) => { const calculateNextEvaluationDate = useCallback((rule: CombinedRule) => {
const isValidLastEvaluation = const isValidLastEvaluation = rule.promRule?.lastEvaluation && isValidDate(rule.promRule.lastEvaluation);
rule.promRule?.lastEvaluation &&
!isNullDate(rule.promRule.lastEvaluation) &&
isValidDate(rule.promRule.lastEvaluation);
const isValidIntervalDuration = rule.group.interval && isValidDuration(rule.group.interval); const isValidIntervalDuration = rule.group.interval && isValidDuration(rule.group.interval);
if (!isValidLastEvaluation || !isValidIntervalDuration) { if (!isValidLastEvaluation || !isValidIntervalDuration || isGrafanaRulerRulePaused(rule)) {
return; return;
} }
const lastEvaluationDate = Date.parse(rule.promRule?.lastEvaluation || '');
const intervalDuration = parseDuration(rule.group.interval!); const intervalDuration = parseDuration(rule.group.interval!);
const lastEvaluationDate = Date.parse(rule.promRule?.lastEvaluation || '');
const nextEvaluationDate = addDurationToDate(lastEvaluationDate, intervalDuration); const nextEvaluationDate = addDurationToDate(lastEvaluationDate, intervalDuration);
//when `nextEvaluationDate` is a past date it means lastEvaluation was more than one evaluation interval ago.
//in this case we use the interval value to show a more generic estimate.
//See https://github.com/grafana/grafana/issues/65125
const isPastDate = isBefore(nextEvaluationDate, new Date());
if (isPastDate) {
return {
humanized: `within ${formatDuration(intervalDuration)}`,
fullDate: `within ${formatDuration(intervalDuration)}`,
};
}
return { return {
humanized: dateTime(nextEvaluationDate).locale('en').fromNow(true), humanized: `in ${dateTime(nextEvaluationDate).locale('en').fromNow(true)}`,
fullDate: dateTimeFormat(nextEvaluationDate, { format: 'YYYY-MM-DD HH:mm:ss' }), fullDate: dateTimeFormat(nextEvaluationDate, { format: 'YYYY-MM-DD HH:mm:ss' }),
}; };
}, []); }, []);
@ -211,9 +220,9 @@ function useColumns(showSummaryColumn: boolean, showGroupColumn: boolean, showNe
renderCell: ({ data: rule }) => { renderCell: ({ data: rule }) => {
const nextEvalInfo = calculateNextEvaluationDate(rule); const nextEvalInfo = calculateNextEvaluationDate(rule);
return ( return (
nextEvalInfo?.fullDate && ( nextEvalInfo && (
<Tooltip placement="top" content={`${nextEvalInfo?.fullDate}`} theme="info"> <Tooltip placement="top" content={`${nextEvalInfo?.fullDate}`} theme="info">
<span>in {nextEvalInfo?.humanized}</span> <span>{nextEvalInfo?.humanized}</span>
</Tooltip> </Tooltip>
) )
); );

Loading…
Cancel
Save