Dashboard: Add Alert icon in library panels (#107723)

* Use panel.id from the dashboard to filter alterts properly

* add unit test

* Fix linting

* add fix back

* fix betterer in test, use same pattern as DashboardDatasourceBehaviour
This commit is contained in:
Alexa Vargas
2025-07-08 15:08:01 +02:00
committed by GitHub
parent e33047bdf1
commit 2e3c2df6bf
2 changed files with 32 additions and 1 deletions

View File

@ -3,13 +3,21 @@ import { of } from 'rxjs';
import { FieldType, LoadingState, PanelData, getDefaultTimeRange, toDataFrame } from '@grafana/data';
import { getPanelPlugin } from '@grafana/data/test';
import { config, setPluginImportUtils, setRunRequest } from '@grafana/runtime';
import { SceneCanvasText, sceneGraph, SceneGridLayout, VizPanel } from '@grafana/scenes';
import {
SceneCanvasText,
SceneDataTransformer,
sceneGraph,
SceneGridLayout,
SceneQueryRunner,
VizPanel,
} from '@grafana/scenes';
import { LibraryPanel } from '@grafana/schema';
import * as libpanels from 'app/features/library-panels/state/api';
import { vizPanelToPanel } from '../serialization/transformSceneToSaveModel';
import { NEW_LINK } from '../settings/links/utils';
import { activateFullSceneTree } from '../utils/test-utils';
import { getPanelIdForVizPanel } from '../utils/utils';
import { DashboardScene } from './DashboardScene';
import { LibraryPanelBehavior } from './LibraryPanelBehavior';
@ -179,6 +187,24 @@ describe('LibraryPanelBehavior', () => {
expect(behaviorClone.state._loadedPanel?.name).toBe('LibraryPanel A');
expect(behaviorClone.state._loadedPanel?.uid).toBe('111');
});
it('should use dashboard panel ID for data provider filtering', async () => {
const { gridItem } = await buildTestSceneWithLibraryPanel();
const vizPanel = gridItem.state.body;
// Get the dashboard panel ID from the VizPanel key
const dashboardPanelId = getPanelIdForVizPanel(vizPanel);
expect(dashboardPanelId).toBe(1); // Based on key 'panel-1'
// Verify the data provider uses the dashboard panel ID for filtering
const dataProvider = vizPanel.state.$data as SceneDataTransformer;
expect(dataProvider).toBeDefined();
// Access the SceneQueryRunner through the SceneDataTransformer
const queryRunner = dataProvider.state?.$data as SceneQueryRunner;
expect(queryRunner?.state?.dataLayerFilter?.panelId).toBe(dashboardPanelId);
});
});
async function buildTestSceneWithLibraryPanel() {

View File

@ -8,6 +8,7 @@ import { PanelModel } from 'app/features/dashboard/state/PanelModel';
import { getLibraryPanel } from 'app/features/library-panels/state/api';
import { createPanelDataProvider } from '../utils/createPanelDataProvider';
import { getPanelIdForVizPanel } from '../utils/utils';
import { VizPanelLinks, VizPanelLinksMenu } from './PanelLinks';
import { panelLinksBehavior } from './PanelMenuBehavior';
@ -50,6 +51,10 @@ export class LibraryPanelBehavior extends SceneObjectBase<LibraryPanelBehaviorSt
const libPanelModel = new PanelModel(libPanel.model);
// Use dashboard panel ID for data layer filtering
const dashboardPanelId = getPanelIdForVizPanel(vizPanel);
libPanelModel.id = dashboardPanelId;
const titleItems: SceneObject[] = [];
titleItems.push(