Alerting: Expose unified alert history component (#110394)

* register exemplary alert rule extention into IRM extension point

* register AlertRuleHistory into IRM's extension point

* support more default filters

* lazy load alert rule extension

* simplify

* rename extension point

* use exposed component, put props type in grafana-data

* rename PluginExtensionPointsInPlugins to PluginExtensionExposedComponents

* Update public/app/features/alerting/unified/components/rules/central-state-history/CentralAlertHistorySceneExposedComponent.tsx

Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>

* export new types from grafana/data and avoid relative import paths

* improve naming of exposed component

---------

Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>
This commit is contained in:
Dominik Broj
2025-09-04 13:56:50 +02:00
committed by GitHub
co-authored by Marcus Andersson
parent 100528e274
commit 4d818292d8
5 changed files with 72 additions and 21 deletions
+2
View File
@@ -568,6 +568,7 @@ export type { FeatureToggles } from './types/featureToggles.gen';
export {
PluginExtensionTypes,
PluginExtensionPoints,
PluginExtensionExposedComponents,
type PluginExtension,
type PluginExtensionLink,
type PluginExtensionComponent,
@@ -588,6 +589,7 @@ export {
type PluginExtensionAddedLinkConfig,
type PluginExtensionAddedFunctionConfig,
type PluginExtensionResourceAttributesContext,
type CentralAlertHistorySceneV1Props,
} from './types/pluginExtensions';
export {
type ScopeDashboardBindingSpec,
@@ -208,6 +208,11 @@ export enum PluginExtensionPoints {
ExtensionSidebar = 'grafana/extension-sidebar/v0-alpha',
}
// Extension Points available in plugins
export enum PluginExtensionExposedComponents {
CentralAlertHistorySceneV1 = 'grafana/central-alert-history-scene/v1',
}
export type PluginExtensionPanelContext = {
pluginId: string;
id: number;
@@ -220,6 +225,12 @@ export type PluginExtensionPanelContext = {
data?: PanelData;
};
export type CentralAlertHistorySceneV1Props = {
defaultLabelsFilter?: string;
defaultTimeRange?: { from: string; to: string };
hideFilters?: boolean;
};
export type PluginExtensionQueryEditorRowAdaptiveTelemetryV1Context = {
/** An ordered list of lower-case [a-z]+ string identifiers to provide context clues of where this component is being embedded and how we might want to consider displaying it */
contextHints?: string[];
@@ -1,7 +1,7 @@
import { css } from '@emotion/css';
import { useEffect, useMemo } from 'react';
import { GrafanaTheme2, VariableHide } from '@grafana/data';
import { CentralAlertHistorySceneV1Props, GrafanaTheme2, VariableHide } from '@grafana/data';
import { Trans, t } from '@grafana/i18n';
import {
CustomVariable,
@@ -58,7 +58,14 @@ export const STATE_FILTER_FROM = 'STATE_FILTER_FROM';
* Both share time range and filter variable from the parent scene.
*/
export const CentralAlertHistoryScene = () => {
export const CentralAlertHistoryScene = ({
defaultLabelsFilter,
defaultTimeRange = {
from: 'now-1h',
to: 'now',
},
hideFilters,
}: CentralAlertHistorySceneV1Props = {}) => {
//track the loading of the central alert state history
useEffect(() => {
@@ -73,6 +80,7 @@ export const CentralAlertHistoryScene = () => {
const labelsFilterVariable = new TextBoxVariable({
name: LABELS_FILTER,
label: t('alerting.central-alert-history-scene.scene.labels-filter-variable.label.labels', 'Labels: '),
...(defaultLabelsFilter && { value: defaultLabelsFilter }),
});
//custom variable for filtering by the current state
@@ -100,25 +108,24 @@ export const CentralAlertHistoryScene = () => {
});
return new EmbeddedScene({
controls: [
new SceneReactObject({
component: LabelFilter,
}),
new SceneReactObject({
component: FilterInfo,
}),
new VariableValueSelectors({}),
new ClearFilterButtonScenesObject({}),
new SceneControlsSpacer(),
new SceneTimePicker({}),
new SceneRefreshPicker({}),
],
controls: hideFilters
? undefined
: [
new SceneReactObject({
component: LabelFilter,
}),
new SceneReactObject({
component: FilterInfo,
}),
new VariableValueSelectors({}),
new ClearFilterButtonScenesObject({}),
new SceneControlsSpacer(),
new SceneTimePicker({}),
new SceneRefreshPicker({}),
],
// use default time range as from 1 hour ago to now, as the limit of the history api is 5000 events,
// and using a wider time range might lead to showing gaps in the events list and the chart.
$timeRange: new SceneTimeRange({
from: 'now-1h',
to: 'now',
}),
$timeRange: new SceneTimeRange(defaultTimeRange),
$variables: new SceneVariableSet({
variables: [labelsFilterVariable, transitionsFromFilterVariable, transitionsToFilterVariable],
}),
@@ -132,7 +139,7 @@ export const CentralAlertHistoryScene = () => {
],
}),
});
}, []);
}, [defaultLabelsFilter, defaultTimeRange, hideFilters]);
// we need to call this to sync the url with the scene state
const isUrlSyncInitialized = useUrlSync(scene);
@@ -297,3 +304,5 @@ const getStyles = (theme: GrafanaTheme2) => {
}),
};
};
export default CentralAlertHistoryScene;
@@ -0,0 +1,13 @@
import { Suspense, lazy } from 'react';
import { CentralAlertHistorySceneV1Props } from '@grafana/data';
const CentralAlertHistoryScene = lazy(() => import('./CentralAlertHistoryScene'));
const CentralAlertHistorySceneExposedComponent = (props: CentralAlertHistorySceneV1Props) => (
<Suspense fallback={'Loading...'}>
<CentralAlertHistoryScene {...props} />
</Suspense>
);
export default CentralAlertHistorySceneExposedComponent;
@@ -1,3 +1,6 @@
import { PluginExtensionExposedComponents } from '@grafana/data';
import CentralAlertHistorySceneExposedComponent from 'app/features/alerting/unified/components/rules/central-state-history/CentralAlertHistorySceneExposedComponent';
import { getCoreExtensionConfigurations } from '../getCoreExtensionConfigurations';
import { AddedComponentsRegistry } from './AddedComponentsRegistry';
@@ -17,8 +20,21 @@ export const pluginExtensionRegistries: PluginExtensionRegistries = {
addedFunctionsRegistry,
};
// Registering core extensions
// Registering core extension links
addedLinksRegistry.register({
pluginId: 'grafana',
configs: getCoreExtensionConfigurations(),
});
// Registering core exposed components
exposedComponentsRegistry.register({
pluginId: 'grafana',
configs: [
{
id: PluginExtensionExposedComponents.CentralAlertHistorySceneV1,
title: 'Central alert history scene',
description: 'Central alert history scene',
component: CentralAlertHistorySceneExposedComponent,
},
],
});