Skip to content

Notification Rule Processing Engine#5

Open
everettbu wants to merge 1 commit into
notification-rule-baselinefrom
notification-rule-enhancements
Open

Notification Rule Processing Engine#5
everettbu wants to merge 1 commit into
notification-rule-baselinefrom
notification-rule-enhancements

Conversation

@everettbu

@everettbu everettbu commented Jul 26, 2025

Copy link
Copy Markdown

Test 5

Summary by CodeRabbit

  • New Features

    • Introduced a unified component for displaying Grafana Prometheus rules in alerting rule lists.
    • Enhanced permission checks for alert rule actions, now supporting both Grafana and Ruler rule types.
  • Bug Fixes

    • Improved handling and display of rule action buttons based on user permissions.
  • Refactor

    • Simplified rule group loader to focus solely on Prometheus rules, removing cross-source rule matching.
    • Streamlined permission logic and component responsibilities for rule actions and menu options.
  • Tests

    • Expanded and updated tests to cover new permission scenarios and UI interactions for rule actions.
  • Chores

    • Removed unused error messages from localization files.

* wip

* Add working actions for GMA rules based on Prom-only API

* Remove Ruler-loader related code for Grafana rules

Co-authored-by: Sonia Augilar <sonia.aguilar@grafana.com>

* Remove outdated tests

* add some comments

* remove commented code

* remove showLocation property

* Add missing mocks in tests

* Add showLocation to GrafanaRuleListItem, improve useAbilities, address PR feedback

* Enhance GrafanaGroupLoader tests: Add permission checks and More button functionality

- Introduced user permission grants for alerting actions in tests.
- Added tests for rendering the More button with action menu options.
- Verified that each rule has its own action buttons and handles permissions correctly.
- Ensured the edit button is not rendered when user lacks edit permissions.
- Confirmed the correct menu actions are displayed when the More button is clicked.

* Update translations

---------

Co-authored-by: Sonia Aguilar <soniaaguilarpeiron@gmail.com>
Co-authored-by: Sonia Augilar <sonia.aguilar@grafana.com>
@coderabbitai

coderabbitai Bot commented Jul 26, 2025

Copy link
Copy Markdown

Walkthrough

This update refactors and simplifies the handling of alerting rule permissions, rule list rendering, and related UI components. It introduces new hooks for permission checks, consolidates rule list item rendering into a single component, removes cross-source rule matching, and updates tests and type definitions to align with these changes. Several obsolete files and error messages are removed.

Changes

File(s) Change Summary
public/app/features/alerting/unified/components/rule-viewer/AlertRuleMenu.tsx Refactored permission checks to use new plural ability hooks for both Ruler and Grafana Prometheus rules, merging their results.
public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx Updated test fixtures to use a specific data source for cloud rule tests.
public/app/features/alerting/unified/components/rules/RulesTable.test.tsx Expanded and updated mocks for new ability hooks; adjusted tests to use plural ability hooks and handle skip tokens.
public/app/features/alerting/unified/hooks/useAbilities.ts Added and refactored hooks for Grafana Prometheus rule abilities; deprecated old hook; improved type safety and logic separation.
public/app/features/alerting/unified/rule-list/FilterView.tsx Switched rendering from removed loader to new unified list item component for Grafana rules.
public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.test.tsx Enhanced tests with permission scenarios, UI interaction checks, and new selectors; removed unused code.
public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx Simplified to only fetch and display Prometheus rules; removed all Ruler rule matching and related logic.
public/app/features/alerting/unified/rule-list/GrafanaRuleListItem.tsx Introduced new component to render all types of Grafana Prometheus rules in the rule list.
public/app/features/alerting/unified/rule-list/GrafanaRuleLoader.tsx Deleted obsolete loader component and related types; logic replaced by new list item component.
public/app/features/alerting/unified/rule-list/components/RuleActionsButtons.V2.tsx Refactored to support both Ruler and Prometheus rules; added helper functions for provisioning and identifier logic; updated permission checks.
public/app/features/alerting/unified/rule-list/hooks/prometheusGroupsGenerator.ts Removed Ruler group prefetching; now only handles Prometheus group caching.
public/app/features/alerting/unified/utils/rules.ts Added utility to check if a Prometheus rule is provisioned by Grafana.
public/app/types/unified-alerting-dto.ts Added optional provenance property to Grafana Prometheus rule type.
public/locales/en-US/grafana.json Removed two unused error messages related to rule detail loading.

Sequence Diagram(s)

sequenceDiagram
    participant UI as Rule List UI
    participant Hooks as Permission Hooks
    participant API as Prometheus API

    UI->>API: Fetch Prometheus rule groups
    UI->>Hooks: Check abilities for each rule (plural hooks)
    Hooks->>API: (if needed) Fetch permissions for rules
    UI->>UI: Render GrafanaRuleListItem for each rule
    UI->>Hooks: On action (edit, silence, etc), check merged permissions
    Note over UI: Actions enabled if allowed by either Ruler or Grafana Prom hooks
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰
Refactored rules, a tidy warren,
Permissions checked from dusk till mornin’.
Rule lists now are unified,
Old loaders gently set aside.
With hooks and types all crisp and neat,
Alerting’s future tastes so sweet!
— Your code rabbit, on review’s beat.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch notification-rule-enhancements

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@everettbu

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2025

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx (1)

67-80: Consider handling empty rule groups explicitly.

While the optional chaining handles undefined groups safely, consider explicitly checking for empty rule arrays to provide better user feedback.

+  const rules = promResponse.data.groups.at(0)?.rules || [];
+  
+  if (rules.length === 0) {
+    return (
+      <Alert
+        title={t('alerting.group-loader.no-rules', 'No rules found in group {{ groupName }}', {
+          groupName: groupIdentifier.groupName,
+        })}
+        severity="info"
+      />
+    );
+  }
+
   return (
     <>
-      {promResponse.data.groups.at(0)?.rules.map((promRule) => {
+      {rules.map((promRule) => {
         return (
           <GrafanaRuleListItem
public/app/features/alerting/unified/hooks/useAbilities.ts (1)

243-245: TODO: Federated rules support is missing.

The federated rules support is currently hardcoded to false. This might impact users who rely on federated rule groups functionality.

Would you like me to help implement the federated rules support or create an issue to track this TODO?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between acdb0e1 and 3e6d620.

📒 Files selected for processing (14)
  • public/app/features/alerting/unified/components/rule-viewer/AlertRuleMenu.tsx (3 hunks)
  • public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx (3 hunks)
  • public/app/features/alerting/unified/components/rules/RulesTable.test.tsx (10 hunks)
  • public/app/features/alerting/unified/hooks/useAbilities.ts (4 hunks)
  • public/app/features/alerting/unified/rule-list/FilterView.tsx (2 hunks)
  • public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.test.tsx (5 hunks)
  • public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx (4 hunks)
  • public/app/features/alerting/unified/rule-list/GrafanaRuleListItem.tsx (1 hunks)
  • public/app/features/alerting/unified/rule-list/GrafanaRuleLoader.tsx (0 hunks)
  • public/app/features/alerting/unified/rule-list/components/RuleActionsButtons.V2.tsx (3 hunks)
  • public/app/features/alerting/unified/rule-list/hooks/prometheusGroupsGenerator.ts (0 hunks)
  • public/app/features/alerting/unified/utils/rules.ts (1 hunks)
  • public/app/types/unified-alerting-dto.ts (1 hunks)
  • public/locales/en-US/grafana.json (0 hunks)
💤 Files with no reviewable changes (3)
  • public/app/features/alerting/unified/rule-list/hooks/prometheusGroupsGenerator.ts
  • public/locales/en-US/grafana.json
  • public/app/features/alerting/unified/rule-list/GrafanaRuleLoader.tsx
🧰 Additional context used
🧬 Code Graph Analysis (6)
public/app/features/alerting/unified/rule-list/FilterView.tsx (1)
public/app/features/alerting/unified/rule-list/GrafanaRuleListItem.tsx (1)
  • GrafanaRuleListItem (26-71)
public/app/features/alerting/unified/utils/rules.ts (1)
public/app/types/unified-alerting-dto.ts (1)
  • PromRuleDTO (162-162)
public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx (2)
public/app/features/alerting/unified/mocks/server/configure.ts (1)
  • mimirDataSource (178-201)
public/app/features/alerting/unified/mocks.ts (1)
  • getCloudRule (711-728)
public/app/features/alerting/unified/components/rule-viewer/AlertRuleMenu.tsx (2)
public/app/features/alerting/unified/hooks/useAbilities.ts (3)
  • useRulerRuleAbilities (207-217)
  • useGrafanaPromRuleAbilities (397-406)
  • skipToken (380-380)
public/app/features/alerting/unified/utils/rules.ts (1)
  • prometheusRuleType (128-137)
public/app/features/alerting/unified/rule-list/components/RuleActionsButtons.V2.tsx (4)
public/app/types/unified-alerting-dto.ts (1)
  • RulerRuleDTO (319-319)
public/app/features/alerting/unified/hooks/useAbilities.ts (3)
  • useRulerRuleAbility (195-205)
  • useGrafanaPromRuleAbility (386-392)
  • skipToken (380-380)
public/app/features/alerting/unified/utils/rules.ts (3)
  • prometheusRuleType (128-137)
  • isProvisionedRule (167-169)
  • isProvisionedPromRule (171-173)
public/app/features/alerting/unified/Analytics.ts (1)
  • logWarning (35-35)
public/app/features/alerting/unified/hooks/useAbilities.ts (3)
public/app/types/unified-alerting-dto.ts (2)
  • RulerRuleDTO (319-319)
  • GrafanaPromRuleDTO (181-181)
public/app/features/alerting/unified/utils/rules.ts (5)
  • isProvisionedRule (167-169)
  • rulerRuleType (111-126)
  • isPluginProvidedRule (272-274)
  • isProvisionedPromRule (171-173)
  • prometheusRuleType (128-137)
public/app/features/alerting/unified/utils/misc.ts (1)
  • isAdmin (272-274)
🪛 Biome (2.1.2)
public/app/features/alerting/unified/rule-list/FilterView.tsx

[error] 157-163: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

🔇 Additional comments (21)
public/app/features/alerting/unified/utils/rules.ts (1)

171-173: LGTM! Well-structured utility function following established patterns.

The isProvisionedPromRule function correctly mirrors the pattern of the existing isProvisionedRule function, providing a consistent way to check provisioning status for Grafana Prometheus rules. The implementation properly combines the type check with the provenance property validation.

public/app/types/unified-alerting-dto.ts (1)

135-135: LGTM! Necessary type extension for provenance support.

The addition of the optional provenance property to GrafanaPromRuleDTOBase correctly provides the data field needed by the new isProvisionedPromRule utility function. The optional typing is appropriate since not all rules will have provenance information.

public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx (1)

10-10: LGTM! Improved test setup with explicit data source configuration.

The changes enhance the test by explicitly using the mimirDataSource for cloud rule tests instead of relying on the default mock data source. This makes the test intent clearer and aligns with the broader refactoring that handles multiple data source types.

Also applies to: 36-36, 87-87

public/app/features/alerting/unified/rule-list/FilterView.tsx (1)

15-15: LGTM! Component import updated correctly.

The import change from GrafanaRuleLoader to GrafanaRuleListItem aligns with the refactoring to simplify rule rendering by removing the separate loading logic.

public/app/features/alerting/unified/rule-list/GrafanaRuleListItem.tsx (1)

1-71: LGTM! Well-structured component with proper type handling.

The GrafanaRuleListItem component is implemented correctly with:

  • Clear props interface with appropriate TypeScript types
  • Proper extraction of common properties from the rule
  • Correct conditional rendering based on rule types using established type guards
  • Consistent integration of action buttons and navigation
  • Appropriate handling of optional props with sensible defaults

The component effectively consolidates rule rendering logic and eliminates the need for separate loading components.

public/app/features/alerting/unified/components/rule-viewer/AlertRuleMenu.tsx (2)

73-79: Good use of conditional hook invocation with skipToken.

The implementation correctly uses skipToken to conditionally skip the Grafana Prometheus rule abilities check when the rule is not a Grafana Prometheus rule. This prevents unnecessary API calls and follows React hook best practices.


89-92: Fix typo in duplicate ability assignment.

There's a typo on line 90 where grafanaDuplicateAbility is incorrectly used for both the extraction and assignment. It should extract from grafanaDuplicateAbility.

Apply this fix:

  const [duplicateSupported, duplicateAllowed] = rulerDuplicateAbility;
-  const [grafanaDuplicateSupported, grafanaDuplicateAllowed] = grafanaDuplicateAbility;
+  const [grafanaDuplicateSupported, grafanaDuplicateAllowed] = grafanaDuplicateAbility;

Likely an incorrect or invalid review comment.

public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.test.tsx (2)

47-64: Well-structured test setup with comprehensive permissions.

The beforeEach hook properly sets up both user permissions and folder access controls, ensuring a consistent test environment. This approach makes the tests more maintainable and reduces duplication.


171-208: Comprehensive menu interaction test with clear documentation.

The test thoroughly verifies menu item rendering based on permissions, with helpful comments explaining which permission enables each action. The verification of both individual items and total count ensures completeness.

public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx (1)

34-41: Good polling configuration for real-time updates.

The component correctly uses the constant RULE_LIST_POLL_INTERVAL_MS for polling, ensuring rules are refreshed regularly. The query parameters are well-structured with limitAlerts: 0 to fetch all alerts.

public/app/features/alerting/unified/components/rules/RulesTable.test.tsx (2)

61-74: Well-structured mock setup with safe defaults.

The mock setup correctly initializes all hooks with restrictive defaults (returning [false, false]), which is a good security practice. The plural hooks properly handle dynamic action arrays.


213-218: Clear separation of mocking concerns for Cloud rules.

The comments clearly explain that Cloud rules only require useRulerRuleAbilities mocking since useGrafanaPromRuleAbilities receives skipToken. This documentation helps maintain the tests and understand the permission model.

Also applies to: 232-237, 252-257, 271-276

public/app/features/alerting/unified/rule-list/components/RuleActionsButtons.V2.tsx (2)

25-29: Good use of RequireAtLeastOne type for mutual exclusivity.

The type definition ensures that at least one of rule or promRule is provided, preventing the component from being called without any rule data. This is a robust type-safe approach.


130-151: Robust identifier construction with proper error handling.

The function handles both rule types appropriately and provides helpful logging when unable to construct an identifier. The use of satisfies for type assertion and returning undefined instead of throwing maintains component stability.

public/app/features/alerting/unified/hooks/useAbilities.ts (7)

17-17: LGTM! Import statement properly updated.

The addition of GrafanaPromRuleDTO to the imports aligns with the new hooks being introduced for handling Grafana Prometheus rules.


24-30: LGTM! Utility imports support the new functionality.

The imported utility functions (isPluginProvidedRule, isProvisionedPromRule, isProvisionedRule, prometheusRuleType, rulerRuleType) are properly utilized throughout the file for rule type checking and permission logic.


219-229: Good deprecation strategy with performance optimization.

The function is properly deprecated with clear guidance to use useAllRulerRuleAbilities. The memoization of groupIdentifierV2 addresses the performance concerns mentioned in the comment about multiple calls for ~80 rules.


287-337: Well-structured implementation for GrafanaPromRuleDTO abilities.

The function properly handles Grafana Prometheus rules with appropriate:

  • Permission checks scoped to 'grafana' source
  • Silence support specific to Grafana rules with folder-level permissions
  • Clear documentation about federated rules limitation
  • Consistent ability mapping with the RulerRuleDTO counterpart

349-378: Clean implementation of folder-based permission checks.

The hook correctly:

  • Handles loading states and missing data gracefully
  • Checks folder-level permissions using the appropriate metadata context
  • Returns a consistent interface matching the existing pattern

380-406: Excellent optimization with skip token pattern.

The skip token implementation provides a clean way to conditionally skip ability checks, avoiding unnecessary computations when the rule is not yet available. This pattern aligns with modern React optimization practices.


208-208: No breaking change detected: making rule optional is backwards compatible

I verified all call sites of useRulerRuleAbilities, useRulerRuleAbility, and useAllRulerRuleAbilities:

  • public/app/features/alerting/unified/components/rule-viewer/AlertRuleMenu.tsx
  • public/app/features/alerting/unified/rule-list/components/RuleActionsButtons.V2.tsx
  • public/app/features/alerting/unified/components/rule-viewer/tabs/AlertVersionHistory.tsx

In every case, a concrete RulerRuleDTO instance is passed, so relaxing the parameter to RulerRuleDTO | undefined does not break existing usage and merely enables future undefined-safe calls.

Comment on lines +157 to 162
<GrafanaRuleListItem
rule={rule}
groupIdentifier={groupIdentifier}
namespaceName={ruleWithOrigin.namespaceName}
showLocation={true}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix missing key prop for React list rendering.

The component replacement logic is correct, but the rendered GrafanaRuleListItem is missing the required key prop for React list items. This can cause rendering issues when the list order changes.

Apply this diff to add the missing key:

                <GrafanaRuleListItem
+                 key={key}
                  rule={rule}
                  groupIdentifier={groupIdentifier}
                  namespaceName={ruleWithOrigin.namespaceName}
                  showLocation={true}
                />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<GrafanaRuleListItem
rule={rule}
groupIdentifier={groupIdentifier}
namespaceName={ruleWithOrigin.namespaceName}
showLocation={true}
/>
<GrafanaRuleListItem
key={key}
rule={rule}
groupIdentifier={groupIdentifier}
namespaceName={ruleWithOrigin.namespaceName}
showLocation={true}
/>
🧰 Tools
🪛 Biome (2.1.2)

[error] 157-163: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

🤖 Prompt for AI Agents
In public/app/features/alerting/unified/rule-list/FilterView.tsx around lines
157 to 162, the GrafanaRuleListItem component is missing the required key prop
for React list rendering. Add a unique key prop to the GrafanaRuleListItem
component, ideally using a unique identifier from the rule object or another
stable unique value to ensure proper rendering and reconciliation by React.

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 2 weeks if no further activity occurs. Please feel free to give a status update or ping for review. Thank you for your contributions!

@github-actions github-actions Bot added the stale label Aug 27, 2025
@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been automatically closed because it has not had any further activity in the last 2 weeks. Thank you for your contributions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants