Skip to content

Notification Rule Processing Engine - #6

Closed
ShashankFC wants to merge 1 commit into
notification-rule-baselinefrom
notification-rule-enhancements
Closed

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

Conversation

@ShashankFC

@ShashankFC ShashankFC commented Dec 31, 2025

Copy link
Copy Markdown
Collaborator

Test 5nn

Summary by CodeRabbit

  • New Features

    • Added a More menu button to rule actions, providing access to silence, duplicate, copy link, export, and delete operations.
  • Bug Fixes

    • Improved permission evaluation for alert rule actions, now correctly handling both Grafana-managed and externally-sourced rules with separate capability checks.
  • Refactor

    • Streamlined rule list display logic for better performance and maintainability.

✏️ Tip: You can customize this high-level summary in your review settings.

nn---n*Replicated from [ai-code-review-evaluation/grafana-coderabbit#5](https://github.com/ai-code-review-evaluation/grafana-coderabbit/pull/5)*

* 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>
@ShashankFC

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jan 12, 2026

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 commented Jan 12, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The pull request refactors alert rule permission checks to support dual-source validation: both Grafana Prometheus rules and Ruler rules can now be evaluated for capabilities independently, with permissions combined via logical OR. Related components are simplified by removing reconciliation logic and consolidating rule rendering paths.

Changes

Cohort / File(s) Summary
Permission & Ability Hooks
public/app/features/alerting/unified/hooks/useAbilities.ts
Adds GrafanaPromRule-specific ability hooks (useAllGrafanaPromRuleAbilities, useGrafanaPromRuleAbility, useGrafanaPromRuleAbilities), updates useRulerRuleAbilities to accept undefined rules, introduces skipToken for conditional evaluation, and refactors permission logic to distinguish Grafana vs. provisioned rule handling.
Rule Menu & Actions
public/app/features/alerting/unified/components/rule-viewer/AlertRuleMenu.tsx, public/app/features/alerting/unified/rule-list/components/RuleActionsButtons.V2.tsx
Replaces single-source permission checks with dual-source capabilities from both ruler-based and Grafana-based hooks; computed actions (pause, delete, duplicate, silence, export) via logical OR of both sources. RuleActionsButtons now accepts either rule or promRule and conditionally renders edit actions.
Grafana Rule List Components
public/app/features/alerting/unified/rule-list/FilterView.tsx, public/app/features/alerting/unified/rule-list/GrafanaRuleListItem.tsx, public/app/features/alerting/unified/rule-list/GrafanaRuleLoader.tsx, public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx
Removes GrafanaRuleLoader and its internal GrafanaRuleListItem; introduces standalone GrafanaRuleListItem component. Simplifies GrafanaGroupLoader by removing Ruler rule reconciliation and rendering rules directly from Prometheus data. FilterView updated to use new component signature.
Rule Type & Utility Functions
public/app/features/alerting/unified/utils/rules.ts, public/app/types/unified-alerting-dto.ts
Adds isProvisionedPromRule() utility and extends GrafanaPromRuleDTOBase with optional provenance field, affecting all derived GrafanaPromRuleDTO types.
Test Files & Permissions Setup
public/app/features/alerting/unified/components/rules/RulesTable.test.tsx, public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx, public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.test.tsx
Adds mocking for plural ability hooks alongside singular variants to support both RuleActionsButtons and AlertRuleMenu. Introduces permission scaffolding helpers and extends test setup with folder-level access control. Updates test assertions to reflect dual-source permission model.
Data Loading & Localization
public/app/features/alerting/unified/rule-list/hooks/prometheusGroupsGenerator.ts, public/locales/en-US/grafana.json
Removes Ruler rule prefetching from Grafana groups generator. Deletes unused error message translations for missing rule details.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 Hopping through dual permissions now,
Ruler and Grafana rules take a bow,
Simplified loading, no more reconcile,
Rules render swift with a hoppy style!
Abilities combined, the path is clear—
A cleaner alert system we hold dear! 🎉

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'Notification Rule Processing Engine' does not match the changeset, which focuses on refactoring Grafana alerting rule UI components, permissions handling, and rule list rendering. Revise the title to accurately reflect the main change, such as 'Refactor Grafana alerting rule UI and permission handling' or 'Add dual-source rule permissions and simplify Grafana rule list rendering'.
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

@ShashankFC

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jan 12, 2026

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: 2

🤖 Fix all issues with AI agents
In @public/app/features/alerting/unified/hooks/useAbilities.ts:
- Around line 287-294: Remove the stray inline comment "// duplicate" in
useAllGrafanaPromRuleAbilities; locate the call to
useIsGrafanaPromRuleEditable(rule) (the const { isEditable, isRemovable, loading
} = useIsGrafanaPromRuleEditable(rule); line) and delete the trailing "//
duplicate" comment so the code and comment history are clean.

In @public/app/features/alerting/unified/rule-list/FilterView.tsx:
- Around line 157-162: The GrafanaRuleListItem rendered inside the .map() is
missing a React key; update the JSX where GrafanaRuleListItem is returned (the
component using props rule, groupIdentifier, namespaceName, showLocation) to
include key={key} (using the destructured key from ruleWithOrigin) to ensure a
stable unique key for list reconciliation.
🧹 Nitpick comments (4)
public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.test.tsx (2)

85-102: Consider verifying the More button's aria-haspopup attribute.

The test checks aria-label and text content, but for accessibility compliance, it would be valuable to also verify that the More button has aria-haspopup="true" or similar attribute indicating it opens a menu.

💡 Optional enhancement for accessibility testing
     // Verify More button accessibility
     expect(moreButton).toHaveAttribute('aria-label', 'More');
     expect(moreButton).toHaveTextContent('More');
+    // Verify dropdown menu indicator for screen readers
+    expect(moreButton).toHaveAttribute('aria-haspopup', 'true');

171-208: Test assumes exactly 4 menu items, which is fragile.

Line 207 asserts menuItems.length equals 4. If a new menu action is added in the future, this test will fail even though the tested functionality works correctly.

♻️ Suggested improvement to reduce test fragility
-    // Verify that the menu contains all 4 expected menu items
-    const menuItems = byRole('menuitem').getAll();
-    expect(menuItems.length).toBe(4);
+    // Verify that all expected menu items are present (minimum expected items)
+    const menuItems = byRole('menuitem').getAll();
+    expect(menuItems.length).toBeGreaterThanOrEqual(4);

Alternatively, remove this assertion entirely since the individual menu item checks above already verify the expected items are present.

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

50-64: Redundant type check at Line 51.

The prometheusRuleType.grafana.alertingRule(rule) guard at line 50 already narrows the type to an alerting rule. The additional check rule.type === PromRuleType.Alerting at line 51 is redundant.

♻️ Simplify redundant type narrowing
   if (prometheusRuleType.grafana.alertingRule(rule)) {
-    const promAlertingRule = rule && rule.type === PromRuleType.Alerting ? rule : undefined;
-    const instancesCount = totalFromStats(promAlertingRule?.totals ?? {});
+    const instancesCount = totalFromStats(rule.totals ?? {});

     return (
       <AlertRuleListItem
         {...commonProps}
         summary={rule.annotations?.summary}
-        state={promAlertingRule?.state}
+        state={rule.state}
         instancesCount={instancesCount}
         operation={operation}
         showLocation={showLocation}
       />
     );
   }
public/app/features/alerting/unified/components/rules/RulesTable.test.tsx (1)

56-73: Good default mock setup, but consider DRY improvement.

The default mocks are well-structured. However, both useRulerRuleAbilities and useGrafanaPromRuleAbilities have nearly identical implementations. Consider extracting a helper.

♻️ Optional: Extract mock factory for plural hooks
// Helper to create default plural hook mock
const createPluralHookMock = () => (_rule: unknown, ...rest: unknown[]) => {
  const actions = rest[rest.length - 1] as unknown[];
  return actions.map(() => [false, false]);
};

// In beforeEach:
mocks.useRulerRuleAbilities.mockImplementation(createPluralHookMock());
mocks.useGrafanaPromRuleAbilities.mockImplementation(createPluralHookMock());
📜 Review details

Configuration used: defaults

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
  • public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx
  • public/app/features/alerting/unified/components/rules/RulesTable.test.tsx
  • public/app/features/alerting/unified/hooks/useAbilities.ts
  • public/app/features/alerting/unified/rule-list/FilterView.tsx
  • public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.test.tsx
  • public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx
  • public/app/features/alerting/unified/rule-list/GrafanaRuleListItem.tsx
  • public/app/features/alerting/unified/rule-list/GrafanaRuleLoader.tsx
  • public/app/features/alerting/unified/rule-list/components/RuleActionsButtons.V2.tsx
  • public/app/features/alerting/unified/rule-list/hooks/prometheusGroupsGenerator.ts
  • public/app/features/alerting/unified/utils/rules.ts
  • public/app/types/unified-alerting-dto.ts
  • public/locales/en-US/grafana.json
💤 Files with no reviewable changes (3)
  • public/locales/en-US/grafana.json
  • public/app/features/alerting/unified/rule-list/GrafanaRuleLoader.tsx
  • public/app/features/alerting/unified/rule-list/hooks/prometheusGroupsGenerator.ts
🧰 Additional context used
🧬 Code graph analysis (6)
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/rule-list/FilterView.tsx (1)
public/app/features/alerting/unified/rule-list/GrafanaRuleListItem.tsx (1)
  • GrafanaRuleListItem (26-71)
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/rule-list/GrafanaRuleListItem.tsx (5)
public/app/types/unified-alerting-dto.ts (1)
  • GrafanaPromRuleDTO (181-181)
public/app/features/alerting/unified/utils/datasource.ts (1)
  • GrafanaRulesSource (36-40)
public/app/features/alerting/unified/rule-list/components/RuleActionsButtons.V2.tsx (1)
  • RuleActionsButtons (41-116)
public/app/features/alerting/unified/utils/rules.ts (1)
  • prometheusRuleType (128-137)
public/app/features/alerting/unified/utils/ruleStats.ts (1)
  • totalFromStats (5-12)
public/app/features/alerting/unified/components/rules/RulesTable.test.tsx (2)
public/app/features/alerting/unified/hooks/useAbilities.ts (5)
  • useRulerRuleAbility (195-205)
  • useAlertRuleAbility (179-185)
  • useGrafanaPromRuleAbility (386-392)
  • useRulerRuleAbilities (207-217)
  • useGrafanaPromRuleAbilities (397-406)
public/app/features/alerting/unified/mocks.ts (1)
  • getGrafanaRule (699-709)
public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.test.tsx (4)
public/app/features/alerting/unified/mocks.ts (1)
  • grantUserPermissions (637-641)
public/app/features/alerting/unified/mocks/server/configure.ts (1)
  • setFolderAccessControl (56-58)
public/app/features/alerting/unified/mocks/grafanaRulerApi.ts (2)
  • grafanaRulerGroup (65-69)
  • grafanaRulerNamespace (26-26)
public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx (1)
  • GrafanaGroupLoader (29-82)
🪛 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)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sqlite (5/8)
🔇 Additional comments (22)
public/app/features/alerting/unified/utils/rules.ts (1)

171-173: LGTM!

The new isProvisionedPromRule function correctly mirrors the existing isProvisionedRule pattern for ruler rules. The type guard prometheusRuleType.grafana.rule(promRule) properly narrows the type to GrafanaPromRuleDTO which includes the provenance property from GrafanaPromRuleDTOBase.

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

130-136: LGTM!

The addition of provenance?: string to GrafanaPromRuleDTOBase is consistent with the existing provenance field on GrafanaRuleDefinition (line 290) and enables provenance checking for Prometheus-sourced Grafana rules.

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

10-10: LGTM!

The test setup correctly uses mimirDataSource() to configure a proper Mimir data source for cloud rule tests, aligning with the dual-source permission handling introduced in this PR.

Also applies to: 36-37, 87-87

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

56-100: LGTM!

The dual-source permission check implementation is well-structured. The pattern of checking both ruler-based and Grafana-based abilities with a logical OR ensures actions are permitted if either source grants permission. The use of skipToken when promRule is not a Grafana rule correctly prevents unnecessary ability checks.

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

25-37: LGTM!

The use of RequireAtLeastOne from type-fest provides good type safety, ensuring consumers must provide at least one of rule or promRule. The component signature clearly expresses this constraint.

Also applies to: 41-41


66-70: Good defensive handling for missing identifier.

Returning null when an editable identifier cannot be constructed is a safe approach that prevents the component from crashing while still allowing parent components to render other content.


118-151: LGTM!

The helper functions getIsProvisioned and getEditableIdentifier cleanly separate concerns and handle both rule sources appropriately. The warning log at line 146 aids debugging when identifier construction fails.

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

43-51: LGTM!

The simplified loading state that only depends on the Prometheus response aligns with the removal of ruler-based data fusion. The skeleton count from expectedRulesCount provides a good loading UX.


66-81: LGTM!

The direct rendering from promResponse.data.groups.at(0)?.rules is clean and handles edge cases safely via optional chaining. The removal of complex ruler-prometheus reconciliation logic significantly simplifies this component.

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

36-43: LGTM! Well-structured UI selectors for menu items.

The grouped menuItems object provides good organization for accessing action menu elements in tests. The regex patterns (/silence/i) provide flexibility for potential i18n variations.


47-63: LGTM! Good permission scaffolding in beforeEach.

The test setup properly grants both user-level permissions via grantUserPermissions and folder-level access control via setFolderAccessControl. The comments explaining what each permission enables (e.g., "For duplicate action", "For export action") improve maintainability.


148-169: The test correctly denies edit permissions. For Grafana-managed alert rules, the edit button visibility depends only on folder-level permissions checked via ctx.hasPermissionInMetadata(), not user-level permissions. The grantUserPermissions call in beforeEach mocks contextSrv.hasPermission() (user-level), which is unused for this rule type. Therefore, overriding setFolderAccessControl to deny AlertingRuleUpdate is sufficient and the test accurately reflects the no-edit-permission scenario.

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

26-48: LGTM! Well-structured component with clear prop extraction.

The component correctly extracts common properties and assembles them into a shared props object. The use of createRelativeUrl ensures consistent URL generation, and GrafanaRulesSource correctly identifies the source.


66-70: LGTM! Good fallback handling for unknown rule types.

The component properly handles recording rules and unknown rule types with appropriate fallback components, ensuring graceful degradation.

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

167-178: LGTM! Comprehensive mock setup for creating/deleting state tests.

The beforeEach properly configures all required hooks with permissive mocks, ensuring the creating/deleting state UI behavior can be tested in isolation from permission concerns.


213-218: LGTM! Cloud rule tests properly use useRulerRuleAbilities.

The comments correctly document that cloud rules use useRulerRuleAbilities while useGrafanaPromRuleAbilities receives skipToken. This aligns with the dual-source validation architecture described in the AI summary.

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


79-93: Remove the unnecessary useGrafanaPromRuleAbility mock from the edit test.

The singular useGrafanaPromRuleAbility hook is not used by either RuleActionsButtons or AlertRuleMenu components. The components use the plural useGrafanaPromRuleAbilities hook for permission checks. The delete test correctly mocks only the required plural hook; the edit test should be updated for consistency by removing the unused singular hook mock at lines 85-87.

Likely an incorrect or invalid review comment.

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

219-229: LGTM! Clean deprecation with proper delegation.

The deprecated useAllAlertRuleAbilities correctly delegates to the new implementation while maintaining backward compatibility. The memoized group identifier conversion prevents unnecessary re-renders.


349-378: LGTM! Well-implemented folder permission check.

The useIsGrafanaPromRuleEditable hook correctly:

  1. Returns early with safe defaults when rule or folderUID is missing
  2. Handles loading state appropriately
  3. Checks folder-specific permissions using hasPermissionInMetadata

380-406: LGTM! Clean skipToken pattern implementation.

The skipToken symbol pattern is a well-established practice (similar to RTK Query's skipToken) for conditionally skipping hook execution. The implementation correctly handles the skip case by passing undefined to the underlying abilities hook.


231-281: Verify memoization dependencies are complete.

Line 278 lists dependencies for the useMemo, but rulesSourceName is derived from groupIdentifier (line 235). If groupIdentifier changes but rulesSourceName stays the same, the memo won't update. This should be fine given the current logic, but it's worth noting for future maintainers.


295-337: Code correctly handles loading state transitions.

The loading dependency is properly included in the dependency array (line 337), and MaybeSupported correctly evaluates to NotSupported during loading. When the loading state changes, useMemo recalculates the abilities, and consuming components automatically re-render with the updated ability values. The loading-to-loaded transition is handled gracefully by React's memoization and equality checks.

Comment on lines +287 to 294
export function useAllGrafanaPromRuleAbilities(rule: GrafanaPromRuleDTO | undefined): Abilities<AlertRuleAction> {
// For GrafanaPromRuleDTO, we use useIsGrafanaPromRuleEditable instead
const { isEditable, isRemovable, loading } = useIsGrafanaPromRuleEditable(rule); // duplicate
const [_, exportAllowed] = useAlertingAbility(AlertingAction.ExportGrafanaManagedRules);
const canSilence = useCanSilence(rule);

const silenceSupported = useGrafanaRulesSilenceSupport();
const canSilenceInFolder = useCanSilenceInFolder(rule?.folderUid);

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 | 🟡 Minor

Duplicate comment on Line 289.

There's a stray "// duplicate" comment at line 289 that appears to be leftover from development.

🧹 Remove stray comment
 export function useAllGrafanaPromRuleAbilities(rule: GrafanaPromRuleDTO | undefined): Abilities<AlertRuleAction> {
   // For GrafanaPromRuleDTO, we use useIsGrafanaPromRuleEditable instead
-  const { isEditable, isRemovable, loading } = useIsGrafanaPromRuleEditable(rule); // duplicate
+  const { isEditable, isRemovable, loading } = useIsGrafanaPromRuleEditable(rule);
   const [_, exportAllowed] = useAlertingAbility(AlertingAction.ExportGrafanaManagedRules);
📝 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
export function useAllGrafanaPromRuleAbilities(rule: GrafanaPromRuleDTO | undefined): Abilities<AlertRuleAction> {
// For GrafanaPromRuleDTO, we use useIsGrafanaPromRuleEditable instead
const { isEditable, isRemovable, loading } = useIsGrafanaPromRuleEditable(rule); // duplicate
const [_, exportAllowed] = useAlertingAbility(AlertingAction.ExportGrafanaManagedRules);
const canSilence = useCanSilence(rule);
const silenceSupported = useGrafanaRulesSilenceSupport();
const canSilenceInFolder = useCanSilenceInFolder(rule?.folderUid);
export function useAllGrafanaPromRuleAbilities(rule: GrafanaPromRuleDTO | undefined): Abilities<AlertRuleAction> {
// For GrafanaPromRuleDTO, we use useIsGrafanaPromRuleEditable instead
const { isEditable, isRemovable, loading } = useIsGrafanaPromRuleEditable(rule);
const [_, exportAllowed] = useAlertingAbility(AlertingAction.ExportGrafanaManagedRules);
const silenceSupported = useGrafanaRulesSilenceSupport();
const canSilenceInFolder = useCanSilenceInFolder(rule?.folderUid);
🤖 Prompt for AI Agents
In @public/app/features/alerting/unified/hooks/useAbilities.ts around lines 287
- 294, Remove the stray inline comment "// duplicate" in
useAllGrafanaPromRuleAbilities; locate the call to
useIsGrafanaPromRuleEditable(rule) (the const { isEditable, isRemovable, loading
} = useIsGrafanaPromRuleEditable(rule); line) and delete the trailing "//
duplicate" comment so the code and comment history are clean.

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 | 🟡 Minor

Missing key prop on list item.

The GrafanaRuleListItem is rendered inside a .map() but is missing the key prop. The key variable is already available from the destructured ruleWithOrigin. Without a key, React cannot efficiently reconcile list updates.

🔧 Proposed fix
             case 'grafana':
               return (
                 <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 - 162, The GrafanaRuleListItem rendered inside the .map() is missing a React
key; update the JSX where GrafanaRuleListItem is returned (the component using
props rule, groupIdentifier, namespaceName, showLocation) to include key={key}
(using the destructured key from ruleWithOrigin) to ensure a stable unique key
for list reconciliation.

@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 Feb 12, 2026
@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!

@github-actions github-actions Bot closed this Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants