Alerting: Allow linking to library panels (#79693)

This commit is contained in:
Gilles De Mey 2023-12-19 17:41:49 +01:00 committed by GitHub
parent 7613ab7a5b
commit 324f7d7534
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 23 deletions

View File

@ -1,4 +1,4 @@
import { act, render } from '@testing-library/react';
import { render, waitFor } from '@testing-library/react';
import { noop } from 'lodash';
import React from 'react';
import { AutoSizerProps } from 'react-virtualized-auto-sizer';
@ -29,7 +29,22 @@ mockDashboardApi(server).dashboard(
mockDashboardDto({
uid: 'dash-2',
title: 'Dashboard 2',
panels: [{ type: 'graph' }, { type: 'timeseries' }],
panels: [
{
type: 'graph',
},
{
type: 'timeseries',
},
// this one is a library panel
{
type: undefined,
libraryPanel: {
name: 'my library panel',
uid: 'abc123',
},
},
],
})
);
@ -38,26 +53,22 @@ const ui = {
};
describe('DashboardPicker', () => {
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
it('Renders panels without ids', async () => {
render(<DashboardPicker isOpen={true} onChange={noop} onDismiss={noop} dashboardUid="dash-2" panelId={2} />, {
wrapper: TestProvider,
});
act(() => {
jest.advanceTimersByTime(500);
await waitFor(() => {
expect(ui.dashboardButton(/Dashboard 1/).get()).toBeInTheDocument();
expect(ui.dashboardButton(/Dashboard 2/).get()).toBeInTheDocument();
expect(ui.dashboardButton(/Dashboard 3/).get()).toBeInTheDocument();
const panels = ui.dashboardButton(/<No title>/).getAll();
expect(panels).toHaveLength(3);
panels.forEach((panel) => {
expect(panel).not.toBeDisabled();
});
});
expect(await ui.dashboardButton(/Dashboard 1/).find()).toBeInTheDocument();
expect(await ui.dashboardButton(/Dashboard 2/).find()).toBeInTheDocument();
expect(await ui.dashboardButton(/Dashboard 3/).find()).toBeInTheDocument();
expect(await ui.dashboardButton(/<No title>/).findAll()).toHaveLength(2);
});
});

View File

@ -81,7 +81,7 @@ export const DashboardPicker = ({ dashboardUid, panelId, isOpen, onChange, onDis
.sort(panelSort) ?? [];
const currentPanel: PanelDTO | undefined = allDashboardPanels.find(
(panel: PanelDTO) => isValidPanelIdentifier(panel) && panel.id?.toString() === selectedPanelId
(panel: PanelDTO) => isValidPanel(panel) && panel.id?.toString() === selectedPanelId
);
const selectedDashboardIndex = useMemo(() => {
@ -135,7 +135,7 @@ export const DashboardPicker = ({ dashboardUid, panelId, isOpen, onChange, onDis
const panelTitle = panel.title || '<No title>';
const isSelected = Boolean(panel.id) && selectedPanelId === panel.id;
const isAlertingCompatible = panel.type === 'graph' || panel.type === 'timeseries';
const disabled = !isValidPanelIdentifier(panel);
const disabled = !isValidPanel(panel);
return (
<button
@ -152,7 +152,7 @@ export const DashboardPicker = ({ dashboardUid, panelId, isOpen, onChange, onDis
{panelTitle}
</div>
{!isAlertingCompatible && !disabled && (
<Tooltip content="Alert tab will be disabled for this panel. It is only supported on graph and timeseries panels">
<Tooltip content="The alert tab and alert annotations are only supported on graph and timeseries panels.">
<Icon name="exclamation-triangle" className={styles.warnIcon} data-testid="warning-icon" />
</Tooltip>
)}
@ -276,8 +276,12 @@ export function getVisualPanels(dashboardModel: DashboardModel | undefined) {
return allDashboardPanels;
}
const isValidPanelIdentifier = (panel: PanelDTO): boolean => {
return typeof panel.id === 'number' && typeof panel.type === 'string';
const isValidPanel = (panel: PanelDTO): boolean => {
const hasValidID = typeof panel.id === 'number';
const isValidPanelType = typeof panel.type === 'string';
const isLibraryPanel = 'libraryPanel' in panel;
return hasValidID && (isValidPanelType || isLibraryPanel);
};
const getPickerStyles = (theme: GrafanaTheme2) => {