mirror of
https://github.com/grafana/grafana.git
synced 2025-08-02 01:15:46 +08:00

* Add group actions menu * Refactor modals to accept raw ruler group * Use prometheus and ruler responses to dispaly GMA rules in the hierarchical view * Add groups loader component for data source managed rules * Improve rules matching algorithm for the search results * Use plus and minus icons for reconciliation state * loading spinner WIP for operations / transactions * update comment * Use ruler rules order when displaying a group, change rurler preload behaviour * Add ruler-based ordering for GMA rules * Refactor ruler API mocking * Refactor rule components to accept ruler only rules * Add tests for GrafanaGroupLoader * Add tests for vanilla prom groups * Unify data matching code, add tests for DS groups loader * Fix errors after rebasing * Improve handling of ruler group absence * Fix cache key * Add group action buttons for the new group pages * Add new rule action buttons to the new list page * Address PR feeback, component renaming, missing translations * Unify groups and rules links and actions * Fix new rule button * Add rule list action buttons tests * Fix lint errors * Add redirect to rule details page on save * Update FilterView tests * Fix imports and remove unused code * Improve type definitions, add pooling to Prom hooks, add inline docs * Remove unused code of group modals * Update translations * Disable cache population for filter-view generators * Add consistency check Alert to the RuleViewer when V2 list is enabled * Disable UI errors in prom generator * Improve missing datasouce handling * Add missing translations * Improve group loader tests, remove unused code * Enhance Prometheus API query to include notification options * Improve error handling, remove consistency check for vanilla prom data sources * Address PR feedback, add new version of the useHasRuler hook --------- Co-authored-by: Gilles De Mey <gilles.de.mey@gmail.com>
106 lines
3.2 KiB
TypeScript
106 lines
3.2 KiB
TypeScript
import { useMemo, useRef } from 'react';
|
|
|
|
import { PluginExtensionLink, PluginExtensionPoints } from '@grafana/data';
|
|
import { usePluginLinks } from '@grafana/runtime';
|
|
import { CombinedRule, Rule, RuleGroupIdentifierV2 } from 'app/types/unified-alerting';
|
|
import { PromRuleType } from 'app/types/unified-alerting-dto';
|
|
|
|
import { getRulePluginOrigin } from '../utils/rules';
|
|
|
|
interface BaseRuleExtensionContext {
|
|
name: string;
|
|
namespace: string;
|
|
group: string;
|
|
expression: string;
|
|
labels: Record<string, string>;
|
|
}
|
|
|
|
export interface AlertingRuleExtensionContext extends BaseRuleExtensionContext {
|
|
annotations: Record<string, string>;
|
|
}
|
|
|
|
export interface RecordingRuleExtensionContext extends BaseRuleExtensionContext {}
|
|
|
|
export function useRulePluginLinkExtension(rule: Rule | undefined, groupIdentifier: RuleGroupIdentifierV2) {
|
|
// This ref provides a stable reference to an empty array, which is used to avoid re-renders when the rule is undefined.
|
|
const emptyResponse = useRef<PluginExtensionLink[]>([]);
|
|
|
|
const ruleExtensionPoint = useRuleExtensionPoint(rule, groupIdentifier);
|
|
const { links } = usePluginLinks(ruleExtensionPoint);
|
|
|
|
if (!rule) {
|
|
return emptyResponse.current;
|
|
}
|
|
|
|
const ruleOrigin = getRulePluginOrigin(rule);
|
|
const ruleType = rule.type;
|
|
if (!ruleOrigin || !ruleType) {
|
|
return emptyResponse.current;
|
|
}
|
|
|
|
const { pluginId } = ruleOrigin;
|
|
|
|
return links.filter((link) => link.pluginId === pluginId);
|
|
}
|
|
|
|
export interface PluginRuleExtensionParam {
|
|
pluginId: string;
|
|
rule: CombinedRule;
|
|
}
|
|
|
|
interface AlertingRuleExtensionPoint {
|
|
extensionPointId: PluginExtensionPoints.AlertingAlertingRuleAction;
|
|
context: AlertingRuleExtensionContext;
|
|
}
|
|
|
|
interface RecordingRuleExtensionPoint {
|
|
extensionPointId: PluginExtensionPoints.AlertingRecordingRuleAction;
|
|
context: RecordingRuleExtensionContext;
|
|
}
|
|
|
|
interface EmptyExtensionPoint {
|
|
extensionPointId: '';
|
|
}
|
|
|
|
type RuleExtensionPoint = AlertingRuleExtensionPoint | RecordingRuleExtensionPoint | EmptyExtensionPoint;
|
|
|
|
function useRuleExtensionPoint(rule: Rule | undefined, groupIdentifier: RuleGroupIdentifierV2): RuleExtensionPoint {
|
|
return useMemo<RuleExtensionPoint>(() => {
|
|
if (!rule) {
|
|
return { extensionPointId: '' };
|
|
}
|
|
|
|
const ruleType = rule.type;
|
|
const { namespace, groupName } = groupIdentifier;
|
|
const namespaceIdentifier = 'uid' in namespace ? namespace.uid : namespace.name;
|
|
|
|
switch (ruleType) {
|
|
case PromRuleType.Alerting:
|
|
return {
|
|
extensionPointId: PluginExtensionPoints.AlertingAlertingRuleAction,
|
|
context: {
|
|
name: rule.name,
|
|
namespace: namespaceIdentifier,
|
|
group: groupName,
|
|
expression: rule.query,
|
|
labels: rule.labels ?? {},
|
|
annotations: rule.annotations ?? {},
|
|
},
|
|
};
|
|
case PromRuleType.Recording:
|
|
return {
|
|
extensionPointId: PluginExtensionPoints.AlertingRecordingRuleAction,
|
|
context: {
|
|
name: rule.name,
|
|
namespace: namespaceIdentifier,
|
|
group: groupName,
|
|
expression: rule.query,
|
|
labels: rule.labels ?? {},
|
|
},
|
|
};
|
|
default:
|
|
return { extensionPointId: '' };
|
|
}
|
|
}, [groupIdentifier, rule]);
|
|
}
|