mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Add FGAC to alerts tab in panel editor (#47732)
* add FGAC for alert panel tab * add test for panel tabs * Refactor condition Co-authored-by: Konrad Lalik <konrad.lalik@grafana.com>
This commit is contained in:
parent
90892050d0
commit
c63086822d
@ -7,6 +7,8 @@ import { NewRuleFromPanelButton } from './components/panel-alerts-tab/NewRuleFro
|
|||||||
import { RulesTable } from './components/rules/RulesTable';
|
import { RulesTable } from './components/rules/RulesTable';
|
||||||
import { usePanelCombinedRules } from './hooks/usePanelCombinedRules';
|
import { usePanelCombinedRules } from './hooks/usePanelCombinedRules';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
|
import { getRulesPermissions } from './utils/access-control';
|
||||||
|
import { contextSrv } from 'app/core/services/context_srv';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
dashboard: DashboardModel;
|
dashboard: DashboardModel;
|
||||||
@ -20,6 +22,8 @@ export const PanelAlertTabContent: FC<Props> = ({ dashboard, panel }) => {
|
|||||||
panel,
|
panel,
|
||||||
poll: true,
|
poll: true,
|
||||||
});
|
});
|
||||||
|
const permissions = getRulesPermissions('grafana');
|
||||||
|
const canCreateRules = contextSrv.hasPermission(permissions.create);
|
||||||
|
|
||||||
const alert = errors.length ? (
|
const alert = errors.length ? (
|
||||||
<Alert title="Errors loading rules" severity="error">
|
<Alert title="Errors loading rules" severity="error">
|
||||||
@ -44,7 +48,7 @@ export const PanelAlertTabContent: FC<Props> = ({ dashboard, panel }) => {
|
|||||||
<div className={styles.innerWrapper}>
|
<div className={styles.innerWrapper}>
|
||||||
{alert}
|
{alert}
|
||||||
<RulesTable rules={rules} />
|
<RulesTable rules={rules} />
|
||||||
{!!dashboard.meta.canSave && (
|
{!!dashboard.meta.canSave && canCreateRules && (
|
||||||
<NewRuleFromPanelButton className={styles.newButton} panel={panel} dashboard={dashboard} />
|
<NewRuleFromPanelButton className={styles.newButton} panel={panel} dashboard={dashboard} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -58,7 +62,7 @@ export const PanelAlertTabContent: FC<Props> = ({ dashboard, panel }) => {
|
|||||||
{!!dashboard.uid && (
|
{!!dashboard.uid && (
|
||||||
<>
|
<>
|
||||||
<p>There are no alert rules linked to this panel.</p>
|
<p>There are no alert rules linked to this panel.</p>
|
||||||
{!!dashboard.meta.canSave && <NewRuleFromPanelButton panel={panel} dashboard={dashboard} />}
|
{!!dashboard.meta.canSave && canCreateRules && <NewRuleFromPanelButton panel={panel} dashboard={dashboard} />}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{!dashboard.uid && !!dashboard.meta.canSave && (
|
{!dashboard.uid && !!dashboard.meta.canSave && (
|
||||||
|
@ -2,6 +2,13 @@ import { getPanelEditorTabs } from './selectors';
|
|||||||
import { PanelPlugin } from '@grafana/data';
|
import { PanelPlugin } from '@grafana/data';
|
||||||
import { PanelEditorTabId } from '../types';
|
import { PanelEditorTabId } from '../types';
|
||||||
import { updateConfig } from '../../../../../core/config';
|
import { updateConfig } from '../../../../../core/config';
|
||||||
|
import { contextSrv } from 'app/core/services/context_srv';
|
||||||
|
|
||||||
|
jest.mock('app/core/services/context_srv');
|
||||||
|
|
||||||
|
const mocks = {
|
||||||
|
contextSrv: jest.mocked(contextSrv),
|
||||||
|
};
|
||||||
|
|
||||||
describe('getPanelEditorTabs selector', () => {
|
describe('getPanelEditorTabs selector', () => {
|
||||||
it('return no tabs when no plugin provided', () => {
|
it('return no tabs when no plugin provided', () => {
|
||||||
@ -79,5 +86,37 @@ describe('getPanelEditorTabs selector', () => {
|
|||||||
expect(tabs[1].id).toEqual(PanelEditorTabId.Transform);
|
expect(tabs[1].id).toEqual(PanelEditorTabId.Transform);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('with unified alerting enabled', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
updateConfig({ unifiedAlertingEnabled: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows the alert tab for users with read permission', () => {
|
||||||
|
mocks.contextSrv.hasPermission.mockReturnValue(true);
|
||||||
|
|
||||||
|
const tabs = getPanelEditorTabs(undefined, {
|
||||||
|
meta: {
|
||||||
|
id: 'graph',
|
||||||
|
},
|
||||||
|
} as PanelPlugin);
|
||||||
|
|
||||||
|
expect(tabs.length).toEqual(3);
|
||||||
|
expect(tabs[2].id).toEqual(PanelEditorTabId.Alert);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('hides the alert tab for users with read permission', () => {
|
||||||
|
mocks.contextSrv.hasPermission.mockReturnValue(false);
|
||||||
|
|
||||||
|
const tabs = getPanelEditorTabs(undefined, {
|
||||||
|
meta: {
|
||||||
|
id: 'graph',
|
||||||
|
},
|
||||||
|
} as PanelPlugin);
|
||||||
|
|
||||||
|
expect(tabs.length).toEqual(2);
|
||||||
|
expect(tabs[1].id).toEqual(PanelEditorTabId.Transform);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,6 +2,9 @@ import memoizeOne from 'memoize-one';
|
|||||||
import { PanelPlugin } from '@grafana/data';
|
import { PanelPlugin } from '@grafana/data';
|
||||||
import { PanelEditorTab, PanelEditorTabId } from '../types';
|
import { PanelEditorTab, PanelEditorTabId } from '../types';
|
||||||
import { getConfig } from 'app/core/config';
|
import { getConfig } from 'app/core/config';
|
||||||
|
import { getRulesPermissions } from 'app/features/alerting/unified/utils/access-control';
|
||||||
|
import { contextSrv } from 'app/core/services/context_srv';
|
||||||
|
import { GRAFANA_RULES_SOURCE_NAME } from 'app/features/alerting/unified/utils/datasource';
|
||||||
|
|
||||||
export const getPanelEditorTabs = memoizeOne((tab?: string, plugin?: PanelPlugin) => {
|
export const getPanelEditorTabs = memoizeOne((tab?: string, plugin?: PanelPlugin) => {
|
||||||
const tabs: PanelEditorTab[] = [];
|
const tabs: PanelEditorTab[] = [];
|
||||||
@ -34,10 +37,14 @@ export const getPanelEditorTabs = memoizeOne((tab?: string, plugin?: PanelPlugin
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
const { alertingEnabled, unifiedAlertingEnabled } = getConfig();
|
||||||
((getConfig().alertingEnabled || getConfig().unifiedAlertingEnabled) && plugin.meta.id === 'graph') ||
|
const hasRuleReadPermissions = contextSrv.hasPermission(getRulesPermissions(GRAFANA_RULES_SOURCE_NAME).read);
|
||||||
plugin.meta.id === 'timeseries'
|
const isAlertingAvailable = alertingEnabled || (unifiedAlertingEnabled && hasRuleReadPermissions);
|
||||||
) {
|
|
||||||
|
const isGraph = plugin.meta.id === 'graph';
|
||||||
|
const isTimeseries = plugin.meta.id === 'timeseries';
|
||||||
|
|
||||||
|
if ((isAlertingAvailable && isGraph) || isTimeseries) {
|
||||||
tabs.push({
|
tabs.push({
|
||||||
id: PanelEditorTabId.Alert,
|
id: PanelEditorTabId.Alert,
|
||||||
text: 'Alert',
|
text: 'Alert',
|
||||||
|
Loading…
Reference in New Issue
Block a user