Skip to content

feat(alert-rule): add section summaries, save-and-stay, batch enable/disable, and event status filter - #2218

Closed
710leo wants to merge 2 commits into
mainfrom
optimize-alert-rule-0727
Closed

feat(alert-rule): add section summaries, save-and-stay, batch enable/disable, and event status filter#2218
710leo wants to merge 2 commits into
mainfrom
optimize-alert-rule-0727

Conversation

@710leo

@710leo 710leo commented Jul 27, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features
    • Filter alert rules by event status (alerting vs OK).
    • Batch enable/disable alert rules.
    • Display contextual “section summary” details for form sections (tags, data sources, rules, notifications, workflows).
    • Show an inline warning when no notification targets are configured.
    • Save changes and remain on the page.
    • Clone alert rules with a translated cloned-name suffix.
    • Improved step-by-step empty-state guide and help/document access.
  • Bug Fixes
    • Prevent “stay” saves from triggering incorrect external-update behavior.
    • Expand and scroll to the relevant section on form validation errors.
  • Documentation
    • Updated localized UI text and guidance across supported languages (including new section summary labels).

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cdaedddc-12da-4d57-8554-c0af928dda11

📥 Commits

Reviewing files that changed from the base of the PR and between a4267b8 and a89fd24.

📒 Files selected for processing (5)
  • src/pages/alertRules/Edit.tsx
  • src/pages/alertRules/FormNG/index.tsx
  • src/pages/alertRules/FormNG/utils/getErrorSectionKey.test.ts
  • src/pages/alertRules/FormNG/utils/getErrorSectionKey.ts
  • src/pages/alertRules/List/MoreOperations.tsx
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/pages/alertRules/Edit.tsx
  • src/pages/alertRules/List/MoreOperations.tsx
  • src/pages/alertRules/FormNG/utils/getErrorSectionKey.test.ts
  • src/pages/alertRules/FormNG/utils/getErrorSectionKey.ts
  • src/pages/alertRules/FormNG/index.tsx

📝 Walkthrough

Walkthrough

Alert rule FormNG sections now show live summaries and coordinated collapse states, with centralized save behavior and validation expansion. Alert-rule lists gain event-status filtering, permission-gated notification lookups, batch enable/disable actions, improved empty-state guidance, cloning labels, and localized strings.

Changes

Alert rule FormNG

Layer / File(s) Summary
Form section summaries and state
src/pages/alertRules/FormNG/Effective/*, src/pages/alertRules/FormNG/Notify/*, src/pages/alertRules/FormNG/PipelineConfigsNG/*, src/pages/alertRules/FormNG/components/SectionSummaries.tsx
Sections receive parent-controlled collapse state and compute localized summaries for effective time, notifications, pipelines, basic fields, data sources, and rules.
Form orchestration and save flow
src/pages/alertRules/FormNG/index.tsx, src/pages/alertRules/FormNG/utils/*, src/pages/alertRules/Edit.tsx
FormNG centralizes save handling, supports staying after save, expands sections containing validation errors, initializes collapse state from form values, and refreshes the edit timestamp after save-in-place operations.
Alert rule list controls
src/pages/alertRules/List/ListNG.tsx, src/pages/alertRules/List/MoreOperations.tsx, src/pages/alertRules/List/index.tsx
The list adds event-status filtering, authorization-gated notification-rule fetching, batch enable/disable actions, and a multi-step empty-state guide with documentation access.
Alert rule localized labels
src/pages/alertRules/locale/*
English, Japanese, Russian, Simplified Chinese, and Traditional Chinese locales add labels for filtering, cloning, warnings, batch actions, onboarding, save actions, and section summaries.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant FormNG
  participant Edit
  User->>FormNG: submit save-in-place
  FormNG->>Edit: save alert rule
  FormNG->>Edit: invoke onSaveStay
  Edit->>Edit: refresh update_at reference
Loading

Possibly related PRs

  • n9e/fe#2144: Refactors the same FormNG section and collapse-state behavior.
  • n9e/fe#2197: Adds related SectionCard summary plumbing used by these changes.
  • n9e/fe#2198: Modifies the related notification section and summary wiring.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main changes in the PR and is specific enough for history scanning.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch optimize-alert-rule-0727

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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: 4

🧹 Nitpick comments (3)
src/pages/alertRules/FormNG/PipelineConfigsNG/index.tsx (1)

71-79: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use native array narrowing in the summary.

Replace _.isArray(...) with Array.isArray(...) for these watched values.

Proposed fix
-    if (_.isArray(eventRelabelConfigValue) && eventRelabelConfigValue.length > 0) {
+    if (Array.isArray(eventRelabelConfigValue) && eventRelabelConfigValue.length > 0) {
       parts.push(`${t('relabel.title')} ${t('form_ng.items_count', { count: eventRelabelConfigValue.length })}`);
     }
-    if (_.isArray(annotationsValue) && annotationsValue.length > 0) {
+    if (Array.isArray(annotationsValue) && annotationsValue.length > 0) {
       parts.push(`${t('annotations')} ${t('form_ng.items_count', { count: annotationsValue.length })}`);
     }
-    if (_.isArray(enrichQueriesValue) && enrichQueriesValue.length > 0) {
+    if (Array.isArray(enrichQueriesValue) && enrichQueriesValue.length > 0) {
       parts.push(`${t('form_ng.enrich_queries_title')} ${t('form_ng.items_count', { count: enrichQueriesValue.length })}`);
     }

As per coding guidelines, “prefer native checks such as Array.isArray … over equivalent Lodash predicates.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/alertRules/FormNG/PipelineConfigsNG/index.tsx` around lines 71 -
79, In the summary-building logic, replace the Lodash _.isArray checks for
eventRelabelConfigValue, annotationsValue, and enrichQueriesValue with native
Array.isArray checks, preserving the existing length conditions and parts.push
behavior.

Source: Coding guidelines

src/pages/alertRules/List/MoreOperations.tsx (1)

118-137: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider a confirmation step before bulk-disabling alert rules.

Unlike the adjacent batch-delete action (which uses Modal.confirm), enable/disable fire immediately on click. Bulk-disabling alert rules silently stops monitoring for potentially many rules at once. The comment above documents this as an intentional low-friction design for drills/change-windows, so this is a suggestion rather than a defect — but consider at least a lightweight confirmation (e.g., a toast showing the affected count) for the "disable" path specifically, given the operational blast radius of unintentionally silencing alerts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/alertRules/List/MoreOperations.tsx` around lines 118 - 137, Update
the disable action in MoreOperations, specifically the batchUpdateDisabled(1)
click handler, to add a lightweight confirmation before applying the bulk
change, such as a toast that includes the affected rule count. Leave the enable
path and existing low-friction design unchanged.
src/pages/alertRules/List/index.tsx (1)

115-170: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the duplicated add/import action logic shared with HeaderExtra.

The new EmptyGuide actions (add button + Import link, canManageInGroup-gated) duplicate the logic already in HeaderExtra (lines 34-62) — same business-group/gids gating and the same Import({...}) call shape, differing only in the refresh callback (fetchData vs getList). Worth extracting into a shared helper/hook to keep the two call sites (and their gating conditions, which already differ slightly: businessGroup.isLeaf && gids !== '-2' in HeaderExtra vs businessGroup.isLeaf && businessGroup.id && gids !== '-2' here) from silently diverging over time.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/alertRules/List/index.tsx` around lines 115 - 170, Extract the
shared add-button and Import-link behavior from HeaderExtra and the EmptyGuide
actions into a common helper or hook, preserving each caller’s existing gating
conditions and refresh callback (getList versus fetchData). Reuse the helper for
the existing Import({...}) parameters and business-group handling without
changing the remaining document or fallback actions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/pages/alertRules/FormNG/Effective/index.tsx`:
- Around line 49-50: Update the all-day detection logic around
isDefaultEffectiveTime in the effective-time form so both documented ranges,
00:00–00:00 and 00:00–23:59, are recognized as default all-day values. Apply the
same condition to the related logic at the additional occurrence, while
preserving the existing enable_status, time_zone, and start-time requirements.

In `@src/pages/alertRules/FormNG/index.tsx`:
- Around line 268-283: Update handleSave to use a synchronous in-flight ref plus
state guard before validation, returning immediately when a save is already
running and setting the guard before dispatching EditStrategy or addStrategy.
Clear the guard in a finally path so it resets on success, validation failure,
or request error, and bind the save buttons’ loading/disabled state to the save
state until completion.
- Around line 284-290: Update the rejection handler around
EditStrategy/addStrategy so scrollToFirstError() runs only when err.errorFields
exists. For other exceptions, replace console.error(err) with the established
user-facing request-failure notification mechanism, ensuring request errors are
displayed without attempting to scroll to a nonexistent field error.

In `@src/pages/alertRules/List/MoreOperations.tsx`:
- Around line 74-95: Add rejection handling to the promise chain in
batchUpdateDisabled after updateAlertRules, displaying an appropriate error
message through the existing message API and reconciling alert-rule state with
getAlertRules when required by the established request-handling pattern.
Preserve the current success and API-error branches.

---

Nitpick comments:
In `@src/pages/alertRules/FormNG/PipelineConfigsNG/index.tsx`:
- Around line 71-79: In the summary-building logic, replace the Lodash _.isArray
checks for eventRelabelConfigValue, annotationsValue, and enrichQueriesValue
with native Array.isArray checks, preserving the existing length conditions and
parts.push behavior.

In `@src/pages/alertRules/List/index.tsx`:
- Around line 115-170: Extract the shared add-button and Import-link behavior
from HeaderExtra and the EmptyGuide actions into a common helper or hook,
preserving each caller’s existing gating conditions and refresh callback
(getList versus fetchData). Reuse the helper for the existing Import({...})
parameters and business-group handling without changing the remaining document
or fallback actions.

In `@src/pages/alertRules/List/MoreOperations.tsx`:
- Around line 118-137: Update the disable action in MoreOperations, specifically
the batchUpdateDisabled(1) click handler, to add a lightweight confirmation
before applying the bulk change, such as a toast that includes the affected rule
count. Leave the enable path and existing low-friction design unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 990ed9c7-86ab-4dbf-bc62-8611a2ed9655

📥 Commits

Reviewing files that changed from the base of the PR and between 205996c and a4267b8.

📒 Files selected for processing (17)
  • src/pages/alertRules/Edit.tsx
  • src/pages/alertRules/FormNG/Effective/index.tsx
  • src/pages/alertRules/FormNG/Notify/index.tsx
  • src/pages/alertRules/FormNG/PipelineConfigsNG/index.tsx
  • src/pages/alertRules/FormNG/components/SectionSummaries.tsx
  • src/pages/alertRules/FormNG/index.tsx
  • src/pages/alertRules/FormNG/utils/getErrorSectionKey.test.ts
  • src/pages/alertRules/FormNG/utils/getErrorSectionKey.ts
  • src/pages/alertRules/FormNG/utils/useScrollSync.ts
  • src/pages/alertRules/List/ListNG.tsx
  • src/pages/alertRules/List/MoreOperations.tsx
  • src/pages/alertRules/List/index.tsx
  • src/pages/alertRules/locale/en_US.ts
  • src/pages/alertRules/locale/ja_JP.ts
  • src/pages/alertRules/locale/ru_RU.ts
  • src/pages/alertRules/locale/zh_CN.ts
  • src/pages/alertRules/locale/zh_HK.ts

Comment on lines 49 to 50
return initialValues.enable_status === true && initialValues.time_zone === 'Local' && isDefaultEffectiveTime(initialValues.effective_time);
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Recognize 00:00–23:59 as all-day.

isDefaultEffectiveTime only accepts an end time of 00:00, although the form explicitly documents 00:00–23:59 as all-day. Those rules will start expanded and show “1 active time window” instead of the all-day summary.

Proposed fix
-  const isDefaultEnd = moment.isMoment(item.enable_etime) && item.enable_etime.format('HH:mm') === '00:00';
+  const isDefaultEnd =
+    moment.isMoment(item.enable_etime) && ['00:00', '23:59'].includes(item.enable_etime.format('HH:mm'));

Also applies to: 62-72

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/alertRules/FormNG/Effective/index.tsx` around lines 49 - 50, Update
the all-day detection logic around isDefaultEffectiveTime in the effective-time
form so both documented ranges, 00:00–00:00 and 00:00–23:59, are recognized as
default all-day values. Apply the same condition to the related logic at the
additional occurrence, while preserving the existing enable_status, time_zone,
and start-time requirements.

Comment on lines +268 to +283
const handleSave = (stay?: boolean) => {
form
.validateFields()
.then(async () => {
const values = form.getFieldsValue(true);
if (!checkBeforeSave(values)) return;
const data = processFormValues(values) as any;
if (type === 1) {
const res = await EditStrategy(data, initialValues.group_id, initialValues.id);
handleMessage(res, stay);
} else {
const curBusiId = initialValues?.group_id || Number(bgid);
const res = await addStrategy([data], curBusiId);
handleMessage(res, stay);
}
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Prevent duplicate save requests.

Line 268 has no synchronous in-flight guard, so rapid clicks can dispatch multiple addStrategy POSTs and create duplicate rules. Guard the whole save flow with a ref/state pair and set the save buttons to loading/disabled until completion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/alertRules/FormNG/index.tsx` around lines 268 - 283, Update
handleSave to use a synchronous in-flight ref plus state guard before
validation, returning immediately when a save is already running and setting the
guard before dispatching EditStrategy or addStrategy. Clear the guard in a
finally path so it resets on success, validation failure, or request error, and
bind the save buttons’ loading/disabled state to the save state until
completion.

Comment on lines +284 to +290
.catch((err) => {
if (err?.errorFields) {
expandErrorSections(err.errorFields);
} else {
console.error(err);
}
scrollToFirstError();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Show request failures instead of scrolling to a nonexistent field error.

When EditStrategy/addStrategy rejects, this logs the error and still calls scrollToFirstError(). Reserve scrolling for errorFields; show a user-facing request failure for other exceptions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/alertRules/FormNG/index.tsx` around lines 284 - 290, Update the
rejection handler around EditStrategy/addStrategy so scrollToFirstError() runs
only when err.errorFields exists. For other exceptions, replace
console.error(err) with the established user-facing request-failure notification
mechanism, ensuring request errors are displayed without attempting to scroll to
a nonexistent field error.

Source: Coding guidelines

Comment on lines +74 to +95
// 批量启停是静默、演练、变更窗口的高频操作,直接一级入口,不必进「批量更新」弹窗选字段
const batchUpdateDisabled = (disabled: 0 | 1) => {
if (selectRowKeys.length === 0) {
message.warning(t('batch.not_select'));
return;
}
updateAlertRules(
{
ids: selectRowKeys,
fields: { disabled },
},
bgid!,
).then((res) => {
if (!res.err) {
message.success(t('common:success.modify'));
getAlertRules();
} else {
message.error(res.err);
}
});
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Add error handling to batchUpdateDisabled.

The updateAlertRules(...).then(...) chain has no .catch(). On network/promise rejection, the request fails silently — no error message, and getAlertRules() never runs to reconcile UI state. This is a bulk operation directly affecting production alert-rule enablement, so a silent failure mode is riskier than for a single-row toggle.

🐛 Proposed fix
     updateAlertRules(
       {
         ids: selectRowKeys,
         fields: { disabled },
       },
       bgid!,
-    ).then((res) => {
+    ).then((res) => {
       if (!res.err) {
         message.success(t('common:success.modify'));
         getAlertRules();
       } else {
         message.error(res.err);
       }
-    });
+    }).catch((error) => {
+      message.error(error?.message || t('common:error.network'));
+    });
   };

As per coding guidelines, "Asynchronous requests must include error handling, such as try/catch, .catch, or onError, consistent with existing patterns."

📝 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
// 批量启停是静默、演练、变更窗口的高频操作,直接一级入口,不必进「批量更新」弹窗选字段
const batchUpdateDisabled = (disabled: 0 | 1) => {
if (selectRowKeys.length === 0) {
message.warning(t('batch.not_select'));
return;
}
updateAlertRules(
{
ids: selectRowKeys,
fields: { disabled },
},
bgid!,
).then((res) => {
if (!res.err) {
message.success(t('common:success.modify'));
getAlertRules();
} else {
message.error(res.err);
}
});
};
// 批量启停是静默、演练、变更窗口的高频操作,直接一级入口,不必进「批量更新」弹窗选字段
const batchUpdateDisabled = (disabled: 0 | 1) => {
if (selectRowKeys.length === 0) {
message.warning(t('batch.not_select'));
return;
}
updateAlertRules(
{
ids: selectRowKeys,
fields: { disabled },
},
bgid!,
)
.then((res) => {
if (!res.err) {
message.success(t('common:success.modify'));
getAlertRules();
} else {
message.error(res.err);
}
})
.catch((error) => {
message.error(error?.message || t('common:error.network'));
});
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/alertRules/List/MoreOperations.tsx` around lines 74 - 95, Add
rejection handling to the promise chain in batchUpdateDisabled after
updateAlertRules, displaying an appropriate error message through the existing
message API and reconciling alert-rule state with getAlertRules when required by
the established request-handling pattern. Preserve the current success and
API-error branches.

Source: Coding guidelines

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.

1 participant