grafana/public/app/features/alerting/unified/components/rules/RuleState.tsx
Alex Moreno 53945afedf
Alerting: Allow alert rule pausing from API (#62326)
* Add is_paused attr to the POST alert rule group endpoint

* Add is_paused to alerting API POST alert rule group

* Fixed tests

* Add is_paused to alerting gettable endpoints

* Fix integration tests

* Alerting: allow to pause existing rules (#62401)

* Display Pause Rule switch in Editing Rule form

* add isPaused property to form interface and dto

* map isPaused prop with is_paused value from DTO

Also update test snapshots

* Append '(Paused)' text on alert list state column when appropriate

* Change Switch styles according to discussion with UX

Also adding a tooltip with info what this means

* Adjust styles

* Fix alignment and isPaused type definition

Co-authored-by: gillesdemey <gilles.de.mey@gmail.com>

* Fix test

* Fix test

* Fix RuleList test

---------

Co-authored-by: gillesdemey <gilles.de.mey@gmail.com>

* wip

* Fix tests and add comments to clarify AlertRuleWithOptionals

* Fix one more test

* Fix tests

* Fix typo in comment

* Fix alert rule(s) cannot be paused via API

* Add integration tests for alerting api pausing flow

* Remove duplicated integration test

---------

Co-authored-by: Virginia Cepeda <virginia.cepeda@grafana.com>
Co-authored-by: gillesdemey <gilles.de.mey@gmail.com>
Co-authored-by: George Robinson <george.robinson@grafana.com>
2023-02-01 13:15:03 +01:00

90 lines
2.4 KiB
TypeScript

import { css } from '@emotion/css';
import React, { FC, useMemo } from 'react';
import { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data';
import { HorizontalGroup, Spinner, useStyles2 } from '@grafana/ui';
import { CombinedRule } from 'app/types/unified-alerting';
import { PromAlertingRuleState } from 'app/types/unified-alerting-dto';
import { isAlertingRule, isRecordingRule, getFirstActiveAt } from '../../utils/rules';
import { AlertStateTag } from './AlertStateTag';
interface Props {
rule: CombinedRule;
isDeleting: boolean;
isCreating: boolean;
isPaused?: boolean;
}
export const RuleState: FC<Props> = ({ rule, isDeleting, isCreating, isPaused }) => {
const style = useStyles2(getStyle);
const { promRule } = rule;
// return how long the rule has been in its firing state, if any
const forTime = useMemo(() => {
if (
promRule &&
isAlertingRule(promRule) &&
promRule.alerts?.length &&
promRule.state !== PromAlertingRuleState.Inactive
) {
// find earliest alert
const firstActiveAt = getFirstActiveAt(promRule);
// calculate time elapsed from earliest alert
if (firstActiveAt) {
return (
<span title={String(firstActiveAt)} className={style.for}>
for{' '}
{intervalToAbbreviatedDurationString(
{
start: firstActiveAt,
end: new Date(),
},
false
)}
</span>
);
}
}
return null;
}, [promRule, style]);
if (isDeleting) {
return (
<HorizontalGroup align="flex-start">
<Spinner />
deleting
</HorizontalGroup>
);
} else if (isCreating) {
return (
<HorizontalGroup align="flex-start">
{' '}
<Spinner />
creating
</HorizontalGroup>
);
} else if (promRule && isAlertingRule(promRule)) {
return (
<HorizontalGroup align="flex-start">
<AlertStateTag state={promRule.state} isPaused={isPaused} />
{forTime}
</HorizontalGroup>
);
} else if (promRule && isRecordingRule(promRule)) {
return <>Recording rule</>;
}
return <>n/a</>;
};
const getStyle = (theme: GrafanaTheme2) => ({
for: css`
font-size: ${theme.typography.bodySmall.fontSize};
color: ${theme.colors.text.secondary};
white-space: nowrap;
padding-top: 2px;
`,
});