mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* Reuse prom groups generator between GMA, external DS and list view * Improve generators, add initial support for GMA in grouped view components * Improve handling of GMA rules * Split componentes into files * Improve error handling, simplify groups grouping * Extract grafana rules component * Reset yarn.lock * Reset yarn.lock 2 * Update filters, adjust file names, add folder display name to GMA rules * Re-enable filtering for cloud rules * Rename AlertRuleLoader * Add missing translations, fix lint errors * Remove unused imports, update translations * Fix responses in BE tests * Update backend tests * Update integration test * Tidy up group page size constants * Add error throwing to getGroups endpoint to prevent grafana usage * Refactor FilterView to remove exhaustive check * Refactor common props for grafana rule rendering * Unify identifiers' discriminators, add comments, minor refactor * Update translations * Remove unnecessary prev page condition, add a few explanations --------- Co-authored-by: fayzal-g <fayzal.ghantiwala@grafana.com> Co-authored-by: Tom Ratcliffe <tom.ratcliffe@grafana.com>
126 lines
4.1 KiB
TypeScript
126 lines
4.1 KiB
TypeScript
import { memo, useMemo } from 'react';
|
|
|
|
import { DataSourceRuleGroupIdentifier, Rule, RuleIdentifier } from 'app/types/unified-alerting';
|
|
|
|
import { alertRuleApi } from '../api/alertRuleApi';
|
|
import { featureDiscoveryApi } from '../api/featureDiscoveryApi';
|
|
import { equal, fromRule, fromRulerRule, stringifyIdentifier } from '../utils/rule-id';
|
|
import { getRulePluginOrigin, isAlertingRule, isRecordingRule } from '../utils/rules';
|
|
import { createRelativeUrl } from '../utils/url';
|
|
|
|
import { AlertRuleListItem, RecordingRuleListItem, UnknownRuleListItem } from './components/AlertRuleListItem';
|
|
import { ActionsLoader, RuleActionsButtons } from './components/RuleActionsButtons.V2';
|
|
|
|
const { useDiscoverDsFeaturesQuery } = featureDiscoveryApi;
|
|
const { useGetRuleGroupForNamespaceQuery } = alertRuleApi;
|
|
|
|
interface DataSourceRuleLoaderProps {
|
|
rule: Rule;
|
|
groupIdentifier: DataSourceRuleGroupIdentifier;
|
|
}
|
|
|
|
export const DataSourceRuleLoader = memo(function DataSourceRuleLoader({
|
|
rule,
|
|
groupIdentifier,
|
|
}: DataSourceRuleLoaderProps) {
|
|
const { rulesSource, namespace, groupName } = groupIdentifier;
|
|
|
|
const ruleIdentifier = fromRule(rulesSource.name, namespace.name, groupName, rule);
|
|
const href = createViewLinkFromIdentifier(ruleIdentifier);
|
|
const originMeta = getRulePluginOrigin(rule);
|
|
|
|
// @TODO work with context API to propagate rulerConfig and such
|
|
const { data: dataSourceInfo } = useDiscoverDsFeaturesQuery({ uid: rulesSource.uid });
|
|
|
|
// @TODO refactor this to use a separate hook (useRuleWithLocation() and useCombinedRule() seems to introduce infinite loading / recursion)
|
|
const {
|
|
isLoading,
|
|
data: rulerRuleGroup,
|
|
// error,
|
|
} = useGetRuleGroupForNamespaceQuery(
|
|
{
|
|
namespace: namespace.name,
|
|
group: groupName,
|
|
rulerConfig: dataSourceInfo?.rulerConfig!,
|
|
},
|
|
{ skip: !dataSourceInfo?.rulerConfig }
|
|
);
|
|
|
|
const rulerRule = useMemo(() => {
|
|
if (!rulerRuleGroup) {
|
|
return;
|
|
}
|
|
|
|
return rulerRuleGroup.rules.find((rule) =>
|
|
equal(fromRulerRule(rulesSource.name, namespace.name, groupName, rule), ruleIdentifier)
|
|
);
|
|
}, [rulesSource, namespace, groupName, ruleIdentifier, rulerRuleGroup]);
|
|
|
|
// 1. get the rule from the ruler API with "ruleWithLocation"
|
|
// 1.1 skip this if this datasource does not have a ruler
|
|
//
|
|
// 2.1 render action buttons
|
|
// 2.2 render provisioning badge and contact point metadata, etc.
|
|
const actions = useMemo(() => {
|
|
if (isLoading) {
|
|
return <ActionsLoader />;
|
|
}
|
|
|
|
if (rulerRule) {
|
|
return <RuleActionsButtons rule={rulerRule} promRule={rule} groupIdentifier={groupIdentifier} compact />;
|
|
}
|
|
|
|
return null;
|
|
}, [groupIdentifier, isLoading, rule, rulerRule]);
|
|
|
|
if (isAlertingRule(rule)) {
|
|
return (
|
|
<AlertRuleListItem
|
|
name={rule.name}
|
|
rulesSource={rulesSource}
|
|
application={dataSourceInfo?.application}
|
|
group={groupName}
|
|
namespace={namespace.name}
|
|
href={href}
|
|
summary={rule.annotations?.summary}
|
|
state={rule.state}
|
|
health={rule.health}
|
|
error={rule.lastError}
|
|
labels={rule.labels}
|
|
isProvisioned={undefined}
|
|
instancesCount={rule.alerts?.length}
|
|
actions={actions}
|
|
origin={originMeta}
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (isRecordingRule(rule)) {
|
|
return (
|
|
<RecordingRuleListItem
|
|
name={rule.name}
|
|
rulesSource={rulesSource}
|
|
application={dataSourceInfo?.application}
|
|
group={groupName}
|
|
namespace={namespace.name}
|
|
href={href}
|
|
health={rule.health}
|
|
error={rule.lastError}
|
|
labels={rule.labels}
|
|
isProvisioned={undefined}
|
|
actions={actions}
|
|
origin={originMeta}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return <UnknownRuleListItem rule={rule} groupIdentifier={groupIdentifier} />;
|
|
});
|
|
|
|
function createViewLinkFromIdentifier(identifier: RuleIdentifier, returnTo?: string) {
|
|
const paramId = encodeURIComponent(stringifyIdentifier(identifier));
|
|
const paramSource = encodeURIComponent(identifier.ruleSourceName);
|
|
|
|
return createRelativeUrl(`/alerting/${paramSource}/${paramId}/view`, returnTo ? { returnTo } : {});
|
|
}
|