mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Add Alerting menu in getPanelMenu
This commit is contained in:
parent
a6f111e23b
commit
a05b358f43
@ -12,8 +12,10 @@ import {
|
||||
} from '@grafana/data';
|
||||
import { AngularComponent, getPluginLinkExtensions } from '@grafana/runtime';
|
||||
import config from 'app/core/config';
|
||||
import { grantUserPermissions } from 'app/features/alerting/unified/mocks';
|
||||
import * as actions from 'app/features/explore/state/main';
|
||||
import { setStore } from 'app/store/store';
|
||||
import { AccessControlAction } from 'app/types';
|
||||
|
||||
import { PanelModel } from '../state';
|
||||
import { createDashboardModelFixture } from '../state/__fixtures__/dashboardFixtures';
|
||||
@ -23,6 +25,7 @@ import { getPanelMenu } from './getPanelMenu';
|
||||
jest.mock('app/core/services/context_srv', () => ({
|
||||
contextSrv: {
|
||||
hasAccessToExplore: () => true,
|
||||
hasPermission: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
@ -38,6 +41,8 @@ describe('getPanelMenu()', () => {
|
||||
beforeEach(() => {
|
||||
getPluginLinkExtensionsMock.mockRestore();
|
||||
getPluginLinkExtensionsMock.mockReturnValue({ extensions: [] });
|
||||
grantUserPermissions([AccessControlAction.AlertingRuleRead, AccessControlAction.AlertingRuleUpdate]);
|
||||
config.unifiedAlertingEnabled = false;
|
||||
});
|
||||
|
||||
it('should return the correct panel menu items', () => {
|
||||
@ -619,4 +624,62 @@ describe('getPanelMenu()', () => {
|
||||
expect(windowOpen).toHaveBeenLastCalledWith(`${testSubUrl}${testUrl}`);
|
||||
});
|
||||
});
|
||||
describe('Alerting menu', () => {
|
||||
it('should render alerting Menu with correct sub menu if user has permissions to read and update alerts ', () => {
|
||||
const panel = new PanelModel({});
|
||||
|
||||
const dashboard = createDashboardModelFixture({});
|
||||
config.unifiedAlertingEnabled = true;
|
||||
grantUserPermissions([AccessControlAction.AlertingRuleRead, AccessControlAction.AlertingRuleUpdate]);
|
||||
const menuItems = getPanelMenu(dashboard, panel);
|
||||
const alertingSubMenu = menuItems.find((i) => i.text === 'Alerting')?.subMenu;
|
||||
|
||||
expect(alertingSubMenu).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
text: 'View all alert rules',
|
||||
}),
|
||||
expect.objectContaining({
|
||||
text: 'Create alert rule from this panel',
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it('should not render create alert submenu item in the Alerting subMenu, if user does not have permissions to update alerts ', () => {
|
||||
const panel = new PanelModel({});
|
||||
const dashboard = createDashboardModelFixture({});
|
||||
|
||||
grantUserPermissions([AccessControlAction.AlertingRuleRead]);
|
||||
config.unifiedAlertingEnabled = true;
|
||||
|
||||
const menuItems = getPanelMenu(dashboard, panel);
|
||||
|
||||
const alertingSubMenu = menuItems.find((i) => i.text === 'Alerting')?.subMenu;
|
||||
|
||||
expect(alertingSubMenu).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
text: 'View all alert rules',
|
||||
}),
|
||||
expect.not.objectContaining({
|
||||
text: 'Create alert rule from this panel',
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
it('should not render Alerting in menu, if user does not have permissions to read update alerts ', () => {
|
||||
const panel = new PanelModel({});
|
||||
|
||||
const dashboard = createDashboardModelFixture({});
|
||||
grantUserPermissions([]);
|
||||
config.unifiedAlertingEnabled = true;
|
||||
|
||||
const menuItems = getPanelMenu(dashboard, panel);
|
||||
|
||||
const alertingSubMenu = menuItems.find((i) => i.text === 'Alerting')?.subMenu;
|
||||
|
||||
expect(alertingSubMenu).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -3,14 +3,18 @@ import {
|
||||
PanelMenuItem,
|
||||
PluginExtensionLink,
|
||||
PluginExtensionPoints,
|
||||
urlUtil,
|
||||
type PluginExtensionPanelContext,
|
||||
} from '@grafana/data';
|
||||
import { AngularComponent, locationService, reportInteraction, getPluginLinkExtensions } from '@grafana/runtime';
|
||||
import { AngularComponent, getPluginLinkExtensions, locationService, reportInteraction } from '@grafana/runtime';
|
||||
import { PanelCtrl } from 'app/angular/panel/panel_ctrl';
|
||||
import config from 'app/core/config';
|
||||
import config, { getConfig } from 'app/core/config';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { getExploreUrl } from 'app/core/utils/explore';
|
||||
import { getRulesPermissions } from 'app/features/alerting/unified/utils/access-control';
|
||||
import { GRAFANA_RULES_SOURCE_NAME } from 'app/features/alerting/unified/utils/datasource';
|
||||
import { panelToRuleFormValues } from 'app/features/alerting/unified/utils/rule-form';
|
||||
import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
|
||||
import { PanelModel } from 'app/features/dashboard/state/PanelModel';
|
||||
import {
|
||||
@ -202,6 +206,77 @@ export function getPanelMenu(
|
||||
subMenu: inspectMenu,
|
||||
});
|
||||
|
||||
const createAlert = async () => {
|
||||
const formValues = await panelToRuleFormValues(panel, dashboard);
|
||||
|
||||
const ruleFormUrl = urlUtil.renderUrl('/alerting/new', {
|
||||
defaults: JSON.stringify(formValues),
|
||||
returnTo: location.pathname + location.search,
|
||||
});
|
||||
|
||||
locationService.push(ruleFormUrl);
|
||||
};
|
||||
|
||||
const navigateToAlertListView = async () => {
|
||||
const alertListUrl = urlUtil.renderUrl('/alerting/list', {
|
||||
returnTo: location.pathname + location.search,
|
||||
});
|
||||
|
||||
locationService.push(alertListUrl);
|
||||
};
|
||||
|
||||
const onNavigateToAlertListView = (event: React.MouseEvent) => {
|
||||
event.preventDefault();
|
||||
navigateToAlertListView();
|
||||
reportInteraction('dashboards_panelheader_menu', { item: 'create-alert' });
|
||||
};
|
||||
|
||||
const onCreateAlert = (event: React.MouseEvent) => {
|
||||
event.preventDefault();
|
||||
createAlert();
|
||||
reportInteraction('dashboards_panelheader_menu', { item: 'create-alert' });
|
||||
};
|
||||
|
||||
const { unifiedAlertingEnabled } = getConfig();
|
||||
const hasRuleReadPermissions = contextSrv.hasPermission(getRulesPermissions(GRAFANA_RULES_SOURCE_NAME).read);
|
||||
const hasRuleUpdatePermissions = contextSrv.hasPermission(getRulesPermissions(GRAFANA_RULES_SOURCE_NAME).update);
|
||||
const isAlertingAvailableForRead = unifiedAlertingEnabled && hasRuleReadPermissions;
|
||||
|
||||
const alertingMenuAvailable = isAlertingAvailableForRead;
|
||||
if (alertingMenuAvailable) {
|
||||
// prepare submenu depending on permissions
|
||||
const subMenu: PanelMenuItem[] = [];
|
||||
if (hasRuleUpdatePermissions) {
|
||||
subMenu.push({
|
||||
text: t('panel.header-menu.create-alert', `Create alert rule from this panel`),
|
||||
onClick: (e: React.MouseEvent) => onCreateAlert(e),
|
||||
});
|
||||
}
|
||||
subMenu.push({
|
||||
text: t('panel.header-menu.view-alerts', `View all alert rules`),
|
||||
onClick: (e: React.MouseEvent) => onNavigateToAlertListView(e),
|
||||
});
|
||||
|
||||
menu.push({
|
||||
type: 'submenu',
|
||||
text: t('panel.header-menu.alerting', `Alerting`),
|
||||
iconClassName: 'bell',
|
||||
onClick: (e: React.MouseEvent<HTMLElement>) => {
|
||||
const currentTarget = e.currentTarget;
|
||||
const target = e.target;
|
||||
|
||||
if (
|
||||
target === currentTarget ||
|
||||
(target instanceof HTMLElement && target.closest('[role="menuitem"]') === currentTarget)
|
||||
) {
|
||||
onInspectPanel();
|
||||
}
|
||||
},
|
||||
shortcut: 'a',
|
||||
subMenu: subMenu,
|
||||
});
|
||||
}
|
||||
|
||||
const subMenu: PanelMenuItem[] = [];
|
||||
const canEdit = dashboard.canEditPanel(panel);
|
||||
if (!(panel.isViewing || panel.isEditing)) {
|
||||
|
Loading…
Reference in New Issue
Block a user