This is an automated email from the ASF dual-hosted git repository.

lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git


The following commit(s) were added to refs/heads/rocketmq-studio by this push:
     new 71a3bac2c fix(web): name the alert rule window aggregations instead of 
printing the API codes (#6678)
71a3bac2c is described below

commit 71a3bac2c64ad204ead6fb967a340b9cc1190f43
Author: bai mengxuan <[email protected]>
AuthorDate: Thu Oct 15 18:18:50 2026 +0800

    fix(web): name the alert rule window aggregations instead of printing the 
API codes (#6678)
    
    The rule editor's 窗口聚合 select offered `LAST` / `MAX` / `MIN` / `AVG` / 
`SUM` as its visible
    labels while every other field of the same form is named (规则名称, 持续时间, 重提醒间隔,
    窗口秒数, 连续采样次数), so the operator had to guess what `LAST` aggregates - the 
newest sample
    in the window, which is exactly what the code does not say.
    
    The five values the backend accepts (`AlertRuleRequestDTO`) now resolve 
through the dictionary. A
    value without a label would still be printed unchanged, and the payload 
sent to the API keeps the
    codes.
    
    Co-authored-by: iloveeyjafjalla <[email protected]>
---
 web/src/i18n/translations.ts                    |  5 +++++
 web/src/pages/ops/__tests__/AlertsPage.test.tsx | 21 +++++++++++++++++++++
 web/src/pages/ops/alerts.tsx                    | 15 +++++++++++++--
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/web/src/i18n/translations.ts b/web/src/i18n/translations.ts
index 5407a970c..9de093590 100644
--- a/web/src/i18n/translations.ts
+++ b/web/src/i18n/translations.ts
@@ -1163,6 +1163,11 @@ const translations: Record<string, Record<Lang, string>> 
= {
   },
   'alerts.durationRequired': { zh: '请选择持续时间', en: 'Select a duration' },
   'alerts.windowAggregation': { zh: '窗口聚合', en: 'Window aggregation' },
+  'alerts.aggregation.LAST': { zh: '最近一次', en: 'Latest' },
+  'alerts.aggregation.MAX': { zh: '最大值', en: 'Maximum' },
+  'alerts.aggregation.MIN': { zh: '最小值', en: 'Minimum' },
+  'alerts.aggregation.AVG': { zh: '平均值', en: 'Average' },
+  'alerts.aggregation.SUM': { zh: '总和', en: 'Sum' },
   'alerts.windowSeconds': { zh: '窗口秒数', en: 'Window seconds' },
   'alerts.windowRetentionHelp': {
     zh: '聚合只使用本地当前保留的指标快照。当前保留周期之外的历史数据不可用;调整保留时间不会使规则失效。',
diff --git a/web/src/pages/ops/__tests__/AlertsPage.test.tsx 
b/web/src/pages/ops/__tests__/AlertsPage.test.tsx
index f28c77382..40c537159 100644
--- a/web/src/pages/ops/__tests__/AlertsPage.test.tsx
+++ b/web/src/pages/ops/__tests__/AlertsPage.test.tsx
@@ -290,6 +290,27 @@ describe('AlertsPage', () => {
     ).toBeInTheDocument();
   });
 
+  it('names the window aggregations instead of printing the API codes', async 
() => {
+    const user = userEvent.setup();
+    renderPage('BUSINESS');
+
+    await user.click(await screen.findByRole('button', { name: '新建规则' }));
+
+    // The default value is LAST; the selection already reads as its name.
+    expect(await screen.findByText('最近一次')).toBeInTheDocument();
+
+    await user.click(screen.getByRole('combobox', { name: '窗口聚合' }));
+
+    // The visible option list, not the hidden aria mirror that keeps the raw 
value.
+    await waitFor(() =>
+      expect(
+        
Array.from(document.querySelectorAll('.ant-select-item-option-content')).map((option)
 =>
+          option.textContent?.trim(),
+        ),
+      ).toEqual(['最近一次', '最大值', '最小值', '平均值', '总和']),
+    );
+  });
+
   it('formats the last triggered timestamp instead of rendering the raw ISO 
value', async () => {
     const lastTriggered = '2026-08-23T10:35:38.590731';
     vi.mocked(listAlertRulesPage).mockResolvedValue(
diff --git a/web/src/pages/ops/alerts.tsx b/web/src/pages/ops/alerts.tsx
index cf943b4bd..33fbcc9e0 100644
--- a/web/src/pages/ops/alerts.tsx
+++ b/web/src/pages/ops/alerts.tsx
@@ -88,6 +88,17 @@ const channelColors: Record<string, string> = {
 
 const durationOptions = ['1m', '5m', '15m', '30m'];
 const reminderIntervalOptions = ['5m', '15m', '30m', '1h', '4h'];
+/**
+ * The aggregation values the backend accepts (`AlertRuleRequestDTO` rejects 
anything else), named
+ * for the console: `LAST` is the newest sample in the window, which the bare 
code does not say.
+ */
+const aggregationLabelKeys: Record<string, string> = {
+  LAST: 'alerts.aggregation.LAST',
+  MAX: 'alerts.aggregation.MAX',
+  MIN: 'alerts.aggregation.MIN',
+  AVG: 'alerts.aggregation.AVG',
+  SUM: 'alerts.aggregation.SUM',
+};
 const notificationTemplateVariables = ALERT_NOTIFICATION_TEMPLATE_VARIABLES;
 const availabilityMetrics = new Set([
   'nameserver.availability',
@@ -1268,9 +1279,9 @@ const AlertsPageContent = ({ domain = 'CLUSTER' }: 
AlertsPageProps) => {
 
             <Form.Item name="aggregation" 
label={t('alerts.windowAggregation')} initialValue="LAST">
               <Select
-                options={['LAST', 'MAX', 'MIN', 'AVG', 'SUM'].map((value) => ({
-                  label: value,
+                options={Object.entries(aggregationLabelKeys).map(([value, 
labelKey]) => ({
                   value,
+                  label: t(labelKey),
                 }))}
               />
             </Form.Item>

Reply via email to