From 7847651f0c7cf96fee4d38e4a30d522d04f12a4a Mon Sep 17 00:00:00 2001 From: Virginia Cepeda Date: Mon, 27 Mar 2023 10:31:42 -0300 Subject: [PATCH] Alerting: Improve showing nextEvaluationDate for rules (#65205) (#65223) * Improve showing nextEvaluationDate for rules Co-Authored-By: Konrad Lalik * Improve imports and comments --------- Co-authored-by: Konrad Lalik (cherry picked from commit b90aed4fd761a34fba0027a3b89b800b5a1a1953) --- .../unified/components/rules/RulesTable.tsx | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/public/app/features/alerting/unified/components/rules/RulesTable.tsx b/public/app/features/alerting/unified/components/rules/RulesTable.tsx index b04b12b8960..efc99353a39 100644 --- a/public/app/features/alerting/unified/components/rules/RulesTable.tsx +++ b/public/app/features/alerting/unified/components/rules/RulesTable.tsx @@ -1,4 +1,5 @@ import { css, cx } from '@emotion/css'; +import { isBefore, formatDuration } from 'date-fns'; import React, { FC, useCallback, useMemo } from 'react'; import { @@ -17,7 +18,6 @@ import { DEFAULT_PER_PAGE_PAGINATION } from '../../../../../core/constants'; import { useHasRuler } from '../../hooks/useHasRuler'; import { Annotation } from '../../utils/constants'; import { isGrafanaRulerRule } from '../../utils/rules'; -import { isNullDate } from '../../utils/time'; import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable'; import { DynamicTableWithGuidelines } from '../DynamicTableWithGuidelines'; import { ProvisioningBadge } from '../Provisioning'; @@ -116,21 +116,30 @@ function useColumns(showSummaryColumn: boolean, showGroupColumn: boolean, showNe const { hasRuler, rulerRulesLoaded } = useHasRuler(); const calculateNextEvaluationDate = useCallback((rule: CombinedRule) => { - const isValidLastEvaluation = - rule.promRule?.lastEvaluation && - !isNullDate(rule.promRule.lastEvaluation) && - isValidDate(rule.promRule.lastEvaluation); + const isValidLastEvaluation = 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 lastEvaluationDate = Date.parse(rule.promRule?.lastEvaluation || ''); 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 { - 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' }), }; }, []); @@ -208,9 +217,9 @@ function useColumns(showSummaryColumn: boolean, showGroupColumn: boolean, showNe renderCell: ({ data: rule }) => { const nextEvalInfo = calculateNextEvaluationDate(rule); return ( - nextEvalInfo?.fullDate && ( + nextEvalInfo && ( - in {nextEvalInfo?.humanized} + {nextEvalInfo?.humanized} ) );