diff --git a/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreview.tsx b/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreview.tsx index 0e75531c986..71b05c172cb 100644 --- a/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreview.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreview.tsx @@ -4,8 +4,10 @@ import { useEffectOnce } from 'react-use'; import { GrafanaTheme2 } from '@grafana/data'; import { Trans, t } from '@grafana/i18n'; -import { Button, LoadingPlaceholder, Stack, Text, Tooltip, useStyles2 } from '@grafana/ui'; +import { Alert, Button, LoadingPlaceholder, Stack, Text, Tooltip, useStyles2 } from '@grafana/ui'; +import { contextSrv } from 'app/core/services/context_srv'; import { alertRuleApi } from 'app/features/alerting/unified/api/alertRuleApi'; +import { AccessControlAction } from 'app/types/accessControl'; import { AlertQuery, Labels } from 'app/types/unified-alerting-dto'; import { Folder, KBObjectArray } from '../../../types/rule-form'; @@ -36,6 +38,7 @@ export const NotificationPreview = ({ alertUid, }: NotificationPreviewProps) => { const styles = useStyles2(getStyles); + const previewRoutingDisabled = !condition || !folder; const [trigger, { data = [], isLoading, isUninitialized: previewUninitialized }] = preview.useMutation(); @@ -67,9 +70,7 @@ export const NotificationPreview = ({ }; useEffectOnce(() => { - if (!previewRoutingDisabled) { - onPreview(); - } + onPreview(); }); // Get alert managers's data source information @@ -77,18 +78,18 @@ export const NotificationPreview = ({ const singleAlertManagerConfigured = alertManagerDataSources.length === 1; const getTooltipContent = () => { + if (!condition) { + return ( + + Select a query condition to preview routing + + ); + } if (!folder) { return ( Select a folder to preview routing ); } - if (previewRoutingDisabled) { - return ( - - You don't have sufficient permissions to preview - - ); - } return ''; }; @@ -146,10 +147,12 @@ export const NotificationPreview = ({ )} {alertManagerSource.name === 'grafana' ? ( - + + + ) : ( {children}; + } + + return ( + + + You don't have permission to view notification policies. Preview is not available. + + + ); +} + const getStyles = (theme: GrafanaTheme2) => ({ firstAlertManagerLine: css({ height: '1px', diff --git a/public/app/features/alerting/unified/hooks/useAbilities.ts b/public/app/features/alerting/unified/hooks/useAbilities.ts index 5dd43d6db63..5635a3d666a 100644 --- a/public/app/features/alerting/unified/hooks/useAbilities.ts +++ b/public/app/features/alerting/unified/hooks/useAbilities.ts @@ -125,6 +125,22 @@ const AlwaysSupported = true; const NotSupported = false; export type Action = AlertmanagerAction | AlertingAction | AlertRuleAction | FolderBulkAction; + +/** + * Represents the ability to perform an action, with two distinct checks: + * + * @param actionSupported - Whether the action is technically possible in the current context. + * This depends on system capabilities (e.g., API availability), feature availability + * (e.g., Grafana vs external alertmanager), and rule state (e.g., provisioned/immutable rules). + * Examples: Can't edit provisioned rules, can't export from external alertmanagers. + * + * @param actionAllowed - Whether the user has permission to perform the action. + * This is based on RBAC permissions, folder-specific permissions, and admin status. + * Examples: User lacks AlertingRuleUpdate permission, user can't edit in this folder. + * + * Both must be true for an action to be available. This separation allows showing appropriate + * messages: "Feature not available" vs "You don't have permission". + */ export type Ability = [actionSupported: boolean, actionAllowed: boolean]; export type Abilities = Record; diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index 8793ca25bdf..0c9b8b63682 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -1982,9 +1982,11 @@ }, "notification-preview": { "alertmanager": "Alertmanager:", - "disabled-tooltip": "You don't have sufficient permissions to preview", "error": "Could not load routing preview for {{alertmanager}}", "initialized": "Based on the labels added, alert instances are routed to the following notification policies. Expand each notification policy below to view more details.", + "no-condition-tooltip": "Select a query condition to preview routing", + "permission-warning": "Preview not available", + "permission-warning-message": "You don't have permission to view notification policies. Preview is not available.", "preview-routing": "Preview routing", "select-folder-tooltip": "Select a folder to preview routing", "text-loading-preview": "Loading preview...",