Skip to content

Conversation

@akshayutture-augment
Copy link

@akshayutture-augment akshayutture-augment commented Nov 14, 2025

Test 5

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced rule action menu with unified support for pause, delete, duplicate, silence, and export operations across multiple rule sources.
    • Improved permission-based visibility of rule actions based on user access controls.
  • Bug Fixes

    • Simplified rule list display to prevent data synchronization issues between multiple sources.
  • Documentation

    • Removed outdated error messages for rule detail lookups.

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


Replicated from ai-code-review-evaluation/grafana-coderabbit#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 <[email protected]>

* 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 <[email protected]>
Co-authored-by: Sonia Augilar <[email protected]>
@akshayutture-augment
Copy link
Author

@coderabbitai review

@akshayutture-augment
Copy link
Author

@coderabbitai review

1 similar comment
@akshayutture-augment
Copy link
Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 22, 2025

✅ 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
Copy link

coderabbitai bot commented Nov 22, 2025

Walkthrough

The changes add Grafana Prometheus rule support throughout the alerting system by introducing new RBAC hooks for granular permissions, simplifying data-fetching components to rely solely on Prometheus data, consolidating GrafanaRuleLoader logic into a new GrafanaRuleListItem component, enhancing RuleActionsButtons to support both rule types, and updating corresponding tests.

Changes

Cohort / File(s) Summary
RBAC Hooks & Abilities
public/app/features/alerting/unified/hooks/useAbilities.ts
Major refactor adding GrafanaPromRuleDTO support alongside RulerRuleDTO. Introduced new hooks: useAllGrafanaPromRuleAbilities, useGrafanaPromRuleAbility, useGrafanaPromRuleAbilities, useIsGrafanaPromRuleEditable; exported skipToken symbol; updated useRulerRuleAbilities to accept undefined rules; integrated Grafana-specific permission checks including silence and edit/delete capabilities.
Component & Menu Ability Usage
public/app/features/alerting/unified/components/rule-viewer/AlertRuleMenu.tsx, public/app/features/alerting/unified/rule-list/components/RuleActionsButtons.V2.tsx
Updated to use combined ability hooks (useRulerRuleAbilities + useGrafanaPromRuleAbilities) for permission checks. RuleActionsButtons refactored to accept either rule or promRule via RequireAtLeastOne type; added grafana-specific ability checks and identifier retrieval helpers.
Grafana Rule List Components
public/app/features/alerting/unified/rule-list/GrafanaRuleListItem.tsx (new), public/app/features/alerting/unified/rule-list/GrafanaRuleLoader.tsx (deleted), public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx
Introduced new GrafanaRuleListItem component to render Grafana-specific rule items with support for alerting, recording, and unknown rule types. Deleted GrafanaRuleLoader as logic consolidates into new component. Simplified GrafanaGroupLoader to use only Prometheus group data (removed Ruler integration and cross-source matching).
Filter & List Integration
public/app/features/alerting/unified/rule-list/FilterView.tsx, public/app/features/alerting/unified/rule-list/hooks/prometheusGroupsGenerator.ts
Swapped GrafanaRuleLoader component reference to GrafanaRuleListItem with updated props (rule object instead of ruleIdentifier, added showLocation flag). Removed prefetch of Grafana ruler group data from cache population.
Rule Type & DTO Updates
public/app/features/alerting/unified/utils/rules.ts, public/app/types/unified-alerting-dto.ts
Added isProvisionedPromRule helper function for Prometheus rule provisioning checks. Extended GrafanaPromRuleDTOBase interface with optional provenance field.
Test Updates
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/rule-list/GrafanaGroupLoader.test.tsx
Updated RuleDetails.test to use mimirDataSource in Cloud rule setup. Migrated RulesTable.test from singular to plural RBAC hooks with mocks for useGrafanaPromRuleAbility/useGrafanaPromRuleAbilities and useRulerRuleAbilities. Expanded GrafanaGroupLoader.test with permission scaffolding, More button menu testing, and permission-denied scenarios.
Localization
public/locales/en-US/grafana.json
Removed two rule detail error translation entries: "cannot-find-rule-details-for" and "cannot-load-rule-details-for".

Sequence Diagram(s)

sequenceDiagram
    participant Consumer as AlertRuleMenu/<br/>RuleActionsButtons
    participant RulerHook as useRulerRuleAbilities
    participant GrafanaHook as useGrafanaPromRuleAbilities
    participant AbilityCalc as Ability Computation<br/>(both sources)
    participant UI as UI Rendering

    Consumer->>RulerHook: Request abilities for ruler rule
    RulerHook->>AbilityCalc: Compute ruler-based permissions
    Consumer->>GrafanaHook: Request abilities for grafana rule
    GrafanaHook->>AbilityCalc: Compute grafana-specific permissions<br/>(folder perms, silence support)
    AbilityCalc-->>Consumer: canPause, canDelete, canDuplicate...<br/>(OR of both sources)
    Consumer->>UI: Render enabled/disabled menu items
Loading
sequenceDiagram
    participant OldFlow as Old: GrafanaGroupLoader<br/>(Prometheus + Ruler)
    participant NewFlow as New: GrafanaGroupLoader<br/>(Prometheus only)
    participant Renderer as GrafanaRuleListItem<br/>(new component)

    OldFlow->>OldFlow: useGetGrafanaGroupsQuery
    OldFlow->>OldFlow: useGetGrafanaRulerGroupQuery
    OldFlow->>OldFlow: matchRules (cross-source)
    OldFlow->>OldFlow: Render matched + ruler-only items
    
    NewFlow->>NewFlow: useGetGrafanaGroupsQuery
    NewFlow->>Renderer: Prometheus rules only
    Renderer->>Renderer: Determine rule type<br/>(alerting/recording/unknown)
    Renderer->>UI: Render appropriate<br/>list item component
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • useAbilities.ts – Substantial hook refactoring with new Grafana-specific logic, permission checks, and skipToken pattern; requires careful review of memoization dependencies and control-flow branches for both Ruler and Grafana rule paths.
  • Component restructuring – Removal of GrafanaRuleLoader and introduction of GrafanaRuleListItem consolidates logic; verify correct prop threading and rule type handling across alerting/recording/unknown branches.
  • RuleActionsButtons.V2.tsx – New RequireAtLeastOne union type and dual rule/promRule handling; ensure identifier retrieval and provisioning checks work correctly for both sources.
  • Test suite expansion (GrafanaGroupLoader.test.tsx) – Permission scaffolding and menu item assertions are substantial; verify all RBAC scenarios (permitted/denied actions) are properly exercised.
  • Test migration (RulesTable.test.tsx) – Shift from singular to plural hooks with corresponding mock adjustments; confirm return shapes (arrays vs. booleans) match hook contract.

Poem

🐰 Rules now dance both ways with glee,
Grafana and Ruler in harmony!
Permissions flow with skipToken's grace,
Loaders simplified—a cleaner place.
Abilities compute from each source true,
Old complexity replaced by the new.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'Notification Rule Processing Engine' does not match the actual changes, which focus on alerting rule ability checks and RBAC hook refactoring for Grafana and Ruler rules. Update the title to accurately reflect the main changes, such as 'Refactor alert rule ability checks to support Grafana and Ruler rules' or 'Add combined RBAC hooks for Grafana and Ruler alert rules'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch notification-rule-enhancements

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx (1)

24-28: Guard against empty groups array when mapping rules

The code at line 68 has a critical bug: promResponse.data.groups.at(0)?.rules.map(...) will throw a TypeError when groups is an empty array. Optional chaining (?.) only protects the access to rules—it does not prevent .map() from being called on undefined when at(0) returns undefined.

Consider defensively defaulting to an empty array before mapping:

-  return (
-    <>
-      {promResponse.data.groups.at(0)?.rules.map((promRule) => {
-        return (
-          <GrafanaRuleListItem
-            key={promRule.uid}
-            rule={promRule}
-            groupIdentifier={groupIdentifier}
-            namespaceName={namespaceName}
-            // we don't show the location again for rules, it's redundant because they are shown in a folder > group hierarchy
-            showLocation={false}
-          />
-        );
-      })}
-    </>
-  );
+  const rules = promResponse.data.groups.at(0)?.rules ?? [];
+
+  return (
+    <>
+      {rules.map((promRule) => (
+        <GrafanaRuleListItem
+          key={promRule.uid}
+          rule={promRule}
+          groupIdentifier={groupIdentifier}
+          namespaceName={namespaceName}
+          // we don't show the location again for rules, it's redundant because they are shown in a folder > group hierarchy
+          showLocation={false}
+        />
+      ))}
+    </>
+  );

Also consider updating the JSDoc block (lines 24–28) to remove the Ruler reference, as this loader queries Prometheus only.

🧹 Nitpick comments (9)
public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx (1)

36-37: Consider creating mimirDs in beforeEach for better test isolation.

The current implementation works correctly, but creating the data source at module level means it's shared across all tests. While there's no visible mutation in the current tests, moving this to beforeEach would follow best practices for test isolation and prevent potential future issues.

Example refactor:

-const { dataSource: mimirDs } = mimirDataSource();
-
 beforeAll(() => {
   jest.clearAllMocks();
 });
 
+let mimirDs: ReturnType<typeof mimirDataSource>['dataSource'];
+
 beforeEach(() => {
+  mimirDs = mimirDataSource().dataSource;
   mocks.usePluginLinksMock.mockReturnValue({
public/app/features/alerting/unified/components/rule-viewer/AlertRuleMenu.tsx (1)

13-18: Dual abilities wiring looks sound; consider small refactor for maintainability

The new pattern of fetching ruler and Grafana-prom abilities and then OR-ing the (supported && allowed) flags for canPause/Delete/Duplicate/Silence/Export is logically consistent and keeps existing menu rendering intact. The skipToken guard on useGrafanaPromRuleAbilities is also a good way to avoid unnecessary work when promRule isn’t a Grafana-prom rule.

Given the repetition, you might consider extracting a tiny helper like combineAbility([supported, allowed], [gSupported, gAllowed]) to reduce duplication and keep the mapping between requested actions and canX flags easier to maintain going forward, but that’s optional.

Also applies to: 41-43, 56-100

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

18-71: Grafana rule list item composition and actions wiring look correct

This component cleanly centralizes Grafana-prom rule rendering:

  • Common metadata (name, source, namespace, href, health/error, labels, paused state) is shared via commonProps.
  • isProvisioned deriving from provenance matches the provisioning helpers elsewhere.
  • Alerting vs recording routing via prometheusRuleType.grafana.* plus the explicit type === PromRuleType.Alerting check is defensive and clear.
  • Actions are correctly delegated to RuleActionsButtons with promRule and groupIdentifier, which should keep RBAC behavior consistent with other list items.

If you want to DRY things up slightly, you could consider using isProvisionedPromRule(rule) instead of Boolean(provenance), but that’s purely optional.

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

5-63: Expanded RBAC- and menu-focused tests for Grafana groups look solid

The updated tests do a good job of covering:

  • Permission scaffolding (grantUserPermissions + setFolderAccessControl) for the common happy-path.
  • Presence and accessibility of the More button per rule, including multi-rule groups and correct Edit URLs.
  • Negative case where folder-level edit permissions are revoked while still keeping the More button visible.
  • Menu behavior when clicking More, asserting the expected menu structure and primary actions (silence, copy link, duplicate, export).

You’ve also prepared a menuItems.delete query helper; if delete behavior is expected to surface in some scenarios, you might add a small test asserting its presence/absence under the right permissions, but that’s a nice-to-have, not a blocker.

Also applies to: 85-208

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

7-15: RBAC hook mocking setup is clear but jest resets are redundant

The consolidated mocks object and neutral defaults in beforeEach make the RBAC matrix easy to reason about, and correctly distinguish singular vs plural hooks.

You are calling jest.clearAllMocks(), jest.restoreAllMocks(), and jest.resetAllMocks() together, which partially overlap in behaviour and can be confusing. In most cases, a single jest.resetAllMocks() (or a clear + restore pair) is sufficient.

Also applies to: 22-32, 55-74

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

51-62: Combined ruler + Grafanaability checks and identifier guard look correct

  • getIsProvisioned(rule, promRule) unifies provisioned status for both Ruler and Grafana Prom rules.
  • canEditRule short‑circuits correctly when either the Ruler or Grafana ability tuple is [true, true].
  • getEditableIdentifier returning undefined and the component bailing out early avoids rendering partial UI when an identifier can’t be safely constructed, which is preferable to crashing AlertRuleMenu.

One thing to double‑check is that useRulerRuleAbility behaves sensibly when rule is undefined (as will be the case for Grafana‑only Prom rules), and that the extra hook call doesn’t introduce unnecessary work in hot paths. If needed, you could gate it with the same prometheusRuleType/group origin logic you use for Grafana rules.

Also applies to: 66-72, 89-103


118-151: Helper implementations align with existing rule identity semantics

getIsProvisioned correctly defers to isProvisionedRule for ruler rules and isProvisionedPromRule for Grafana Prom rules, with a safe false fallback.

getEditableIdentifier:

  • Delegates ruler rules to ruleId.fromRulerRuleAndGroupIdentifierV2, matching existing patterns.
  • Constructs a minimal GrafanaRuleIdentifier for Grafana Prom rules.
  • Logs a warning and returns undefined otherwise, which is then handled gracefully by the caller.

You might consider enriching the log message with some context (e.g., whether a promRule was present) if debugging this ever becomes necessary, but the current behaviour is functionally sound.

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

231-281: Ruler abilities and silence support need null‑safety verification

useAllRulerRuleAbilities now accepts rule: RulerRuleDTO | undefined and passes it into helpers like:

  • useIsRuleEditable(rulesSourceName, rule)
  • isProvisionedRule(rule)
  • rulerRuleType.grafana.rule(rule)
  • isPluginProvidedRule(rule)
  • useCanSilence(rule)

and useCanSilence itself calls rulerRuleType.grafana.rule(rule) and reads rule.grafana_alert.namespace_uid when appropriate.

This is all fine as long as those helpers are robust to undefined (e.g., short‑circuit early). Please double‑check that isPluginProvidedRule, rulerRuleType.grafana.rule, and related utilities explicitly handle undefined to avoid runtime errors when rule is absent (e.g., Grafana‑only Prom flows).

The updated silence logic (global Grafana AM config + folder‑level permissions) also looks sound and consistent with useGrafanaRulesSilenceSupport.

Also applies to: 560-581, 595-603


339-343: Minor consistency and duplication considerations

A few small things you might consider over time:

  • IsGrafanaPromRuleEditableResult is very similar to what useIsRuleEditable returns; if feasible, aligning the shapes or extracting a shared type could simplify future refactors.
  • useFolderPermissions + useCanSilenceInFolder and useIsGrafanaPromRuleEditable all derive folder‑level permissions; there may be an opportunity to centralize this logic later.
  • toAbility remains the single point for combining support and ACL checks, which keeps the abilities tables readable.

These are non‑blocking and mainly about reducing duplication as the permissions surface grows.

Also applies to: 583-608, 610-615

📜 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/app/features/alerting/unified/rule-list/GrafanaRuleLoader.tsx
  • public/locales/en-US/grafana.json
🧰 Additional context used
🪛 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: Unit tests (5 / 8)
🔇 Additional comments (9)
public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx (2)

10-10: LGTM! Import added to support Cloud rule testing with mimir data source.

The import is used correctly to create a mocked mimir data source for Cloud rule test scenarios.


87-87: LGTM! Cloud rule correctly configured with mimir data source.

The rulesSource parameter is now properly provided to getCloudRule, which aligns with the PR's goal of adding Prometheus rule support. This correctly differentiates Cloud rule setup from Grafana rule setup (line 61), where the data source context is not needed.

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

130-136: Provenance field addition aligns with provisioning logic

Adding provenance?: string to GrafanaPromRuleDTOBase is consistent with how GrafanaRuleDefinition.provenance is used and enables DTO-level provisioning checks (e.g., isProvisionedPromRule, GrafanaRuleListItem.isProvisioned). Just ensure that the backend actually populates this field for provisioned Grafana-prom rules; otherwise these helpers will always treat them as non‑provisioned.

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

8-8: Prom-only loading and error handling look consistent

Using isPromResponseLoading for skeletons and an explicit error Alert when promResponse is missing is straightforward and matches the new single‑source Prometheus flow. No functional issues here.

Also applies to: 43-51, 53-64

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

76-150: Grafana rules RBAC tests cover key edit/delete and lifecycle states

The Grafana rules tests correctly:

  • Use both useAlertRuleAbility and Grafana‑specific hooks to model permissions.
  • Distinguish between update vs delete action tuples.
  • Cover creating/deleting lifecycle states with preloaded ruler state and plural ability hooks.

The expectations (Edit/Delete visibility, hiding view/edit while creating/deleting) align with the encoded ability tuples.

Also applies to: 151-200


203-283: Cloud rules RBAC tests mirror Grafana coverage appropriately

Cloud rule cases correctly:

  • Drive permissions through useRulerRuleAbility / useAlertRuleAbility.
  • Only rely on useRulerRuleAbilities for menu actions, consistent with comments about skipToken for Grafana hooks.
  • Assert the right presence/absence for Edit and Delete under allowed/denied scenarios.

This gives good confidence that RuleActionsButtons + AlertRuleMenu respect RBAC for both rule sources.

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

2-3: Props typing via RequireAtLeastOne is a solid upgrade

Using RequireAtLeastOne for { rule?, promRule? } and threading that through Props ensures at least one rule source is present at compile time, while keeping the external API surface minimal. The added identifier types (EditableRuleIdentifier, GrafanaRuleIdentifier, RuleIdentifier) are consistent with the downstream usage in AlertRuleMenu and RedirectToCloneRule.

Also applies to: 10-17, 25-37, 41-42

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

17-18: Refactor to useAllRulerRuleAbilities with groupIdentifier is a good consolidation

Routing useAlertRuleAbility and useAlertRuleAbilities through useAllAlertRuleAbilities, and then into useAllRulerRuleAbilities(rule.rulerRule, groupIdentifierV2), centralizes the Ruler‑side matrix logic and keeps the public API stable while you migrate callers.

Marking useAllAlertRuleAbilities as deprecated and deriving groupIdentifierV2 via groupIdentifier.fromCombinedRule(rule) is a reasonable bridge strategy.

Also applies to: 22-30, 195-217, 219-229


283-337: Grafana Prom rule abilities and skipToken integration look consistent

  • useAllGrafanaPromRuleAbilities mirrors the Ruler abilities matrix while:

    • Using isProvisionedPromRule and prometheusRuleType.grafana.alertingRule(rule) to distinguish alerting vs recording rules.
    • Removing federated support (explicitly false) and hard‑coding rulesPermissions('grafana').
    • Wiring silence support via useGrafanaRulesSilenceSupport and useCanSilenceInFolder(rule?.folderUid).
  • useIsGrafanaPromRuleEditable correctly bases edit/delete on folder‑scoped permissions, with sensible handling for missing rule/folder and a loading flag feeding back into the abilities.

  • skipToken + useGrafanaPromRuleAbility / useGrafanaPromRuleAbilities provide a clean way to opt out of GrafanaProm evaluation when there is no relevant rule, while still returning a well‑defined ability map.

Overall this is a coherent extension of the existing abilities model to Grafana Prom rules.

Also applies to: 349-378, 380-406

Comment on lines +15 to 16
import { GrafanaRuleListItem } from './GrafanaRuleListItem';
import LoadMoreHelper from './LoadMoreHelper';
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add missing key prop to GrafanaRuleListItem in list rendering

In the rules.map loop, the Grafana branch now renders a <GrafanaRuleListItem> but doesn’t pass the key, which is what Biome is flagging and what React uses for stable reconciliation:

-            case 'grafana':
-              return (
-                <GrafanaRuleListItem
-                  rule={rule}
-                  groupIdentifier={groupIdentifier}
-                  namespaceName={ruleWithOrigin.namespaceName}
-                  showLocation={true}
-                />
-              );
+            case 'grafana':
+              return (
+                <GrafanaRuleListItem
+                  key={key}
+                  rule={rule}
+                  groupIdentifier={groupIdentifier}
+                  namespaceName={ruleWithOrigin.namespaceName}
+                  showLocation={true}
+                />
+              );

This keeps the behavior consistent with the datasource and unknown branches and removes the linter error.

Also applies to: 154-163

🤖 Prompt for AI Agents
In public/app/features/alerting/unified/rule-list/FilterView.tsx around lines
15-16 (and similarly at 154-163), the Grafana branch renders
<GrafanaRuleListItem> inside a rules.map without a React key prop; update the
map to pass a stable unique key (e.g. key={rule.id} or
key={`${rule.datasource}-${rule.uid}`} or fallback to the index) to
GrafanaRuleListItem so its mapping matches the datasource and unknown branches
and resolves the linter/React reconciliation warning.

Comment on lines +171 to +173
export function isProvisionedPromRule(promRule: PromRuleDTO): boolean {
return prometheusRuleType.grafana.rule(promRule) && Boolean(promRule.provenance);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Align isProvisionedPromRule types with DTO shapes

Right now isProvisionedPromRule accepts PromRuleDTO, but provenance is only declared on GrafanaPromRuleDTOBase. From the types in this file, PromRuleDTO doesn’t expose provenance, so promRule.provenance is likely a TS type error.

Two concrete options:

- export function isProvisionedPromRule(promRule: PromRuleDTO): boolean {
-   return prometheusRuleType.grafana.rule(promRule) && Boolean(promRule.provenance);
- }
+ export function isProvisionedPromRule(promRule: GrafanaPromRuleDTO): boolean {
+   return Boolean(promRule.provenance);
+ }

or, if you intentionally want to accept all Prom rules:

-export function isProvisionedPromRule(promRule: PromRuleDTO): boolean {
-  return prometheusRuleType.grafana.rule(promRule) && Boolean(promRule.provenance);
-}
+export function isProvisionedPromRule(promRule: PromRuleDTO | GrafanaPromRuleDTO): boolean {
+  return prometheusRuleType.grafana.rule(promRule) && Boolean((promRule as GrafanaPromRuleDTO).provenance);
+}

Alternatively, you could lift provenance?: string into PromRuleDTOBase if you’re comfortable with it being structurally present on all Prom rules.

📝 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 isProvisionedPromRule(promRule: PromRuleDTO): boolean {
return prometheusRuleType.grafana.rule(promRule) && Boolean(promRule.provenance);
}
export function isProvisionedPromRule(promRule: GrafanaPromRuleDTO): boolean {
return Boolean(promRule.provenance);
}
Suggested change
export function isProvisionedPromRule(promRule: PromRuleDTO): boolean {
return prometheusRuleType.grafana.rule(promRule) && Boolean(promRule.provenance);
}
export function isProvisionedPromRule(promRule: PromRuleDTO | GrafanaPromRuleDTO): boolean {
return prometheusRuleType.grafana.rule(promRule) && Boolean((promRule as GrafanaPromRuleDTO).provenance);
}
🤖 Prompt for AI Agents
In public/app/features/alerting/unified/utils/rules.ts around lines 171-173, the
function accepts PromRuleDTO but accesses provenance which only exists on
GrafanaPromRuleDTOBase; change the signature to a type guard so TypeScript knows
the narrower shape: declare the function as returning promRule is
GrafanaPromRuleDTOBase (e.g. function isProvisionedPromRule(promRule:
PromRuleDTO): promRule is GrafanaPromRuleDTOBase) and keep the runtime check
(prometheusRuleType.grafana.rule(promRule) && Boolean(promRule.provenance));
ensure GrafanaPromRuleDTOBase is imported or in scope. Alternatively, if you
want the function to only accept the Grafana subtype, change the parameter type
to GrafanaPromRuleDTOBase instead of PromRuleDTO, or add provenance?: string to
PromRuleDTOBase if provenance should be available on all Prom rules.

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.

3 participants