mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Move repeated menu item logic for pausing rules into separate component
This commit is contained in:
parent
b84962ef3f
commit
7d80373b5e
78
public/app/features/alerting/unified/MenuItemPauseRule.tsx
Normal file
78
public/app/features/alerting/unified/MenuItemPauseRule.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Menu } from '@grafana/ui';
|
||||
import { alertRuleApi } from 'app/features/alerting/unified/api/alertRuleApi';
|
||||
import { isGrafanaRulerRule, isGrafanaRulerRulePaused } from 'app/features/alerting/unified/utils/rules';
|
||||
import { CombinedRule } from 'app/types/unified-alerting';
|
||||
|
||||
const { useUpdateRuleMutation } = alertRuleApi;
|
||||
|
||||
interface Props {
|
||||
rule: CombinedRule;
|
||||
/**
|
||||
* Method invoked after the request to change the paused state has completed
|
||||
*/
|
||||
onPauseChange?: () => {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu item to display correct text for pausing/resuming an alert,
|
||||
* and triggering API call to do so
|
||||
*/
|
||||
const MenuItemPauseRule = ({ rule, onPauseChange }: Props) => {
|
||||
const { group } = rule;
|
||||
const [updateRule] = useUpdateRuleMutation();
|
||||
const isPaused = isGrafanaRulerRule(rule.rulerRule) && isGrafanaRulerRulePaused(rule.rulerRule);
|
||||
const icon = isPaused ? 'play' : 'pause';
|
||||
const title = isPaused ? 'Resume alert evaluation' : 'Pause alert evaluation';
|
||||
|
||||
/**
|
||||
* Triggers API call to update the current rule to the new `is_paused` state
|
||||
*/
|
||||
const setRulePause = async (newIsPaused: boolean) => {
|
||||
if (!isGrafanaRulerRule(rule.rulerRule)) {
|
||||
return;
|
||||
}
|
||||
const ruleUid = rule.rulerRule.grafana_alert.uid;
|
||||
|
||||
// Parse the rules into correct format for API
|
||||
const modifiedRules = group.rules.map((groupRule) => {
|
||||
if (isGrafanaRulerRule(groupRule.rulerRule) && groupRule.rulerRule.grafana_alert.uid === ruleUid) {
|
||||
return {
|
||||
...groupRule.rulerRule,
|
||||
grafana_alert: {
|
||||
...groupRule.rulerRule.grafana_alert,
|
||||
is_paused: newIsPaused,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return groupRule.rulerRule!;
|
||||
});
|
||||
|
||||
const payload = {
|
||||
interval: group.interval!,
|
||||
name: group.name,
|
||||
rules: modifiedRules,
|
||||
};
|
||||
|
||||
await updateRule({
|
||||
nameSpaceUID: rule.namespace.uid || rule.rulerRule.grafana_alert.namespace_uid,
|
||||
payload,
|
||||
}).unwrap();
|
||||
|
||||
onPauseChange?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu.Item
|
||||
label={title}
|
||||
icon={icon}
|
||||
onClick={() => {
|
||||
setRulePause(!isPaused);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default MenuItemPauseRule;
|
@ -17,7 +17,7 @@ import {
|
||||
Stack,
|
||||
} from '@grafana/ui';
|
||||
import { useAppNotification } from 'app/core/copy/appNotification';
|
||||
import { alertRuleApi } from 'app/features/alerting/unified/api/alertRuleApi';
|
||||
import MenuItemPauseRule from 'app/features/alerting/unified/MenuItemPauseRule';
|
||||
import { INSTANCES_DISPLAY_LIMIT } from 'app/features/alerting/unified/components/rules/RuleDetails';
|
||||
import { useRulesFilter } from 'app/features/alerting/unified/hooks/useFilteredRules';
|
||||
import { useDispatch } from 'app/types';
|
||||
@ -28,13 +28,11 @@ import { deleteRuleAction, fetchAllPromAndRulerRulesAction } from '../../state/a
|
||||
import { getRulesSourceName } from '../../utils/datasource';
|
||||
import { createShareLink, createViewLink } from '../../utils/misc';
|
||||
import * as ruleId from '../../utils/rule-id';
|
||||
import { isGrafanaRulerRule, isGrafanaRulerRulePaused } from '../../utils/rules';
|
||||
import { isGrafanaRulerRule } from '../../utils/rules';
|
||||
import { createUrl } from '../../utils/url';
|
||||
|
||||
import { RedirectToCloneRule } from './CloneRule';
|
||||
|
||||
const { useUpdateRuleMutation } = alertRuleApi;
|
||||
|
||||
export const matchesWidth = (width: number) => window.matchMedia(`(max-width: ${width}px)`).matches;
|
||||
|
||||
interface Props {
|
||||
@ -47,7 +45,6 @@ export const RuleActionsButtons = ({ rule, rulesSource }: Props) => {
|
||||
const location = useLocation();
|
||||
const notifyApp = useAppNotification();
|
||||
const style = useStyles2(getStyles);
|
||||
const [updateRule] = useUpdateRuleMutation();
|
||||
|
||||
const [redirectToClone, setRedirectToClone] = useState<
|
||||
{ identifier: RuleIdentifier; isProvisioned: boolean } | undefined
|
||||
@ -75,47 +72,6 @@ export const RuleActionsButtons = ({ rule, rulesSource }: Props) => {
|
||||
const buttons: JSX.Element[] = [];
|
||||
const moreActions: JSX.Element[] = [];
|
||||
|
||||
/**
|
||||
* Triggers API call to update the current rule to the new `is_paused` state
|
||||
*/
|
||||
const setRulePause = async (newIsPaused: boolean) => {
|
||||
if (!isGrafanaRulerRule(rule.rulerRule)) {
|
||||
return;
|
||||
}
|
||||
const ruleUid = rule.rulerRule.grafana_alert.uid;
|
||||
|
||||
// Parse the rules into correct format for API
|
||||
const modifiedRules = group.rules.map((groupRule) => {
|
||||
if (isGrafanaRulerRule(groupRule.rulerRule) && groupRule.rulerRule.grafana_alert.uid === ruleUid) {
|
||||
return {
|
||||
...groupRule.rulerRule,
|
||||
grafana_alert: {
|
||||
...groupRule.rulerRule.grafana_alert,
|
||||
is_paused: newIsPaused,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return groupRule.rulerRule!;
|
||||
});
|
||||
|
||||
const payload = {
|
||||
interval: group.interval!,
|
||||
name: group.name,
|
||||
rules: modifiedRules,
|
||||
};
|
||||
|
||||
await updateRule({ nameSpaceUID: rule.namespace.uid!, payload }).unwrap();
|
||||
|
||||
// Uses INSTANCES_DISPLAY_LIMIT + 1 here as exporting LIMIT_ALERTS from RuleList has the side effect
|
||||
// of breaking some unrelated tests in Policy.test.tsx due to mocking approach
|
||||
const limitAlerts = hasActiveFilters ? undefined : INSTANCES_DISPLAY_LIMIT + 1;
|
||||
// Trigger a re-fetch of the rules table
|
||||
// TODO: Migrate rules table functionality to RTK Query, so we instead rely
|
||||
// on tag invalidation (or optimistic cache updates) for this
|
||||
await dispatch(fetchAllPromAndRulerRulesAction(false, { limitAlerts }));
|
||||
};
|
||||
|
||||
const deleteRule = () => {
|
||||
if (ruleToDelete && ruleToDelete.rulerRule) {
|
||||
const identifier = ruleId.fromRulerRule(
|
||||
@ -172,15 +128,17 @@ export const RuleActionsButtons = ({ rule, rulesSource }: Props) => {
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
const isPaused = isGrafanaRulerRule(rule.rulerRule) && isGrafanaRulerRulePaused(rule.rulerRule);
|
||||
const icon = isPaused ? 'play' : 'pause';
|
||||
const title = isPaused ? 'Resume alert evaluation' : 'Pause alert evaluation';
|
||||
moreActions.push(
|
||||
<Menu.Item
|
||||
label={title}
|
||||
icon={icon}
|
||||
onClick={() => {
|
||||
setRulePause(!isPaused);
|
||||
<MenuItemPauseRule
|
||||
rule={rule}
|
||||
onPauseChange={async () => {
|
||||
// Uses INSTANCES_DISPLAY_LIMIT + 1 here as exporting LIMIT_ALERTS from RuleList has the side effect
|
||||
// of breaking some unrelated tests in Policy.test.tsx due to mocking approach
|
||||
const limitAlerts = hasActiveFilters ? undefined : INSTANCES_DISPLAY_LIMIT + 1;
|
||||
// Trigger a re-fetch of the rules table
|
||||
// TODO: Migrate rules table functionality to RTK Query, so we instead rely
|
||||
// on tag invalidation (or optimistic cache updates) for this
|
||||
await dispatch(fetchAllPromAndRulerRulesAction(false, { limitAlerts }));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user