From a08069c88241607ab49070efda699c5cf6fdd03f Mon Sep 17 00:00:00 2001 From: Fiona Date: Tue, 12 May 2026 19:50:37 +0800 Subject: [PATCH 01/99] fix(table): set table-body-sort-bg per design spec Per design-system-table.md token baseline, sorted body cells use rgb(var(--fc-fill-5-rgb) / 0.1), not the header bg (fill-2-5). --- scripts/generate_antd_dark_less.js | 4 ++-- scripts/generate_antd_gold_less.js | 4 ++-- vite.config.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/generate_antd_dark_less.js b/scripts/generate_antd_dark_less.js index 26bff30cd..f518af9fe 100644 --- a/scripts/generate_antd_dark_less.js +++ b/scripts/generate_antd_dark_less.js @@ -50,10 +50,10 @@ function saveLess(filePath, filename, callback) { 'table-header-bg': 'var(--fc-fill-2-5)', 'table-header-color': 'var(--fc-text-3)', 'table-header-sort-bg': 'var(--fc-fill-2-5)', - 'table-body-sort-bg': 'var(--fc-fill-2-5)', + 'table-body-sort-bg': 'rgb(var(--fc-fill-5-rgb) / 0.1)', 'table-row-hover-bg': 'rgb(var(--fc-fill-5-rgb) / 0.2)', 'table-selected-row-color': 'inherit', - // Keep Less color functions compile-safe; runtime CSS vars are patched in theme/default.less. + // AntD calls color functions on selected/border tokens; patch runtime CSS vars in theme/default.less. 'table-selected-row-bg': 'rgba(228, 228, 231, 0.15)', 'table-body-selected-sort-bg': '@table-selected-row-bg', 'table-selected-row-hover-bg': 'rgba(228, 228, 231, 0.25)', diff --git a/scripts/generate_antd_gold_less.js b/scripts/generate_antd_gold_less.js index 79b1ddd66..66bf1c303 100644 --- a/scripts/generate_antd_gold_less.js +++ b/scripts/generate_antd_gold_less.js @@ -52,10 +52,10 @@ function saveLess(filePath, filename, callback) { 'table-header-bg': 'var(--fc-fill-2-5)', 'table-header-color': 'var(--fc-text-3)', 'table-header-sort-bg': 'var(--fc-fill-2-5)', - 'table-body-sort-bg': 'var(--fc-fill-2-5)', + 'table-body-sort-bg': 'rgb(var(--fc-fill-5-rgb) / 0.1)', 'table-row-hover-bg': 'rgb(var(--fc-fill-5-rgb) / 0.2)', 'table-selected-row-color': 'inherit', - // Keep Less color functions compile-safe; runtime CSS vars are patched in theme/default.less. + // AntD calls color functions on selected/border tokens; patch runtime CSS vars in theme/default.less. 'table-selected-row-bg': 'rgba(228, 228, 231, 0.15)', 'table-body-selected-sort-bg': '@table-selected-row-bg', 'table-selected-row-hover-bg': 'rgba(228, 228, 231, 0.25)', diff --git a/vite.config.ts b/vite.config.ts index 8fd6c8d6d..8f7552660 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -148,10 +148,10 @@ export default defineConfig(({ mode }) => { 'table-header-bg': 'var(--fc-fill-2-5)', 'table-header-color': 'var(--fc-text-3)', 'table-header-sort-bg': 'var(--fc-fill-2-5)', - 'table-body-sort-bg': 'var(--fc-fill-2-5)', + 'table-body-sort-bg': 'rgb(var(--fc-fill-5-rgb) / 0.1)', 'table-row-hover-bg': 'rgb(var(--fc-fill-5-rgb) / 0.2)', 'table-selected-row-color': 'inherit', - // Keep Less color functions compile-safe; runtime CSS vars are patched in theme/default.less. + // AntD calls color functions on selected/border tokens; patch runtime CSS vars in theme/default.less. 'table-selected-row-bg': 'rgba(228, 228, 231, 0.15)', 'table-body-selected-sort-bg': '@table-selected-row-bg', 'table-selected-row-hover-bg': 'rgba(228, 228, 231, 0.25)', From 5ff8a6d15645b2b571ba765f23b2c41106f50370 Mon Sep 17 00:00:00 2001 From: Fiona Date: Tue, 12 May 2026 19:53:29 +0800 Subject: [PATCH 02/99] =?UTF-8?q?fix(table):=20force=20header=20nowrap=20p?= =?UTF-8?q?er=20design=20rule=20=C2=A75?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Short headers (≤4 chars) must not wrap; wide tables use horizontal scroll instead of squeezing the header. --- src/theme/default.less | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/theme/default.less b/src/theme/default.less index 58997d58a..2d9d8806d 100644 --- a/src/theme/default.less +++ b/src/theme/default.less @@ -85,6 +85,10 @@ mark { border-bottom-color: var(--fc-border-color); } + .ant-table-thead > tr > th { + white-space: nowrap; + } + .ant-table.ant-table-bordered { > .ant-table-title, > .ant-table-footer, From ee0c0cc71e7cd8c01ed5325f43175871a7464a52 Mon Sep 17 00:00:00 2001 From: Fiona Date: Tue, 12 May 2026 19:57:13 +0800 Subject: [PATCH 03/99] fix(table): default pageSize 15 on alert-mutes / alert-subscribes / job-tpls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per design-system-table.md §8: default pageSize is 15 across all tables. - alert-mutes (shield): drop defaultPageSize 30 override; inherit DEFAULT_PAGESIZE. - alert-subscribes (ListNG): drop defaultPageSize 30 override; inherit DEFAULT_PAGESIZE. - job-tpls: add 15 to pageSizeOptions so it is selectable. --- src/pages/taskTpl/index.tsx | 2 +- src/pages/warning/shield/index.tsx | 2 +- src/pages/warning/subscribe/ListNG.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/taskTpl/index.tsx b/src/pages/taskTpl/index.tsx index d9cef3eae..fc74e0b78 100644 --- a/src/pages/taskTpl/index.tsx +++ b/src/pages/taskTpl/index.tsx @@ -264,7 +264,7 @@ const index = (_props: any) => { { ...tableProps.pagination, showSizeChanger: true, - pageSizeOptions: ['10', '50', '100', '500', '1000'], + pageSizeOptions: ['10', '15', '50', '100', '500', '1000'], showTotal: (total) => { return i18n.language == 'en' ? `Total ${total} items` : `共 ${total} 条`; }, diff --git a/src/pages/warning/shield/index.tsx b/src/pages/warning/shield/index.tsx index 51422fb29..771a5c63a 100644 --- a/src/pages/warning/shield/index.tsx +++ b/src/pages/warning/shield/index.tsx @@ -307,7 +307,7 @@ const Shield: React.FC = () => { }, ], ); - const pagination = usePagination({ pageSizeLocalstorageKey: 'alert-mutes-table-pagesize', defaultPageSize: 30, pageSizeOptions: ['30', '50', '100', '300'] }); + const pagination = usePagination({ pageSizeLocalstorageKey: 'alert-mutes-table-pagesize' }); useEffect(() => { getList(); diff --git a/src/pages/warning/subscribe/ListNG.tsx b/src/pages/warning/subscribe/ListNG.tsx index 212228712..0bc79b00f 100644 --- a/src/pages/warning/subscribe/ListNG.tsx +++ b/src/pages/warning/subscribe/ListNG.tsx @@ -345,7 +345,7 @@ const Subscribe = (props: Props) => { }, ], ); - const pagination = usePagination({ pageSizeLocalstorageKey: 'alert-subscribes-table-pagesize', defaultPageSize: 30, pageSizeOptions: ['30', '50', '100', '300'] }); + const pagination = usePagination({ pageSizeLocalstorageKey: 'alert-subscribes-table-pagesize' }); const filterData = () => { const res = _.filter(data, (item: subscribeItem) => { From 1d3dedc3d19d537c5083448cdd402b91ed24bbbb Mon Sep 17 00:00:00 2001 From: Fiona Date: Tue, 12 May 2026 19:59:54 +0800 Subject: [PATCH 04/99] fix(alert-subscribes): combine name + business group into Column1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per design-system-table.md §17.3 PRD scope: - Column1Title: 订阅名称 - Column1Content: 业务组 Drop the standalone business_group column; show group as a sub-line under the subscribe name using the double-row identifier pattern (design-system §5). --- src/pages/warning/subscribe/ListNG.tsx | 35 +++++++++++--------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/pages/warning/subscribe/ListNG.tsx b/src/pages/warning/subscribe/ListNG.tsx index 0bc79b00f..fd8ada69b 100644 --- a/src/pages/warning/subscribe/ListNG.tsx +++ b/src/pages/warning/subscribe/ListNG.tsx @@ -63,35 +63,30 @@ const Subscribe = (props: Props) => { const [notificationRules, setNotificationRules] = useState(); const columns: ColumnsType = _.concat( - hideBusinessGroupColumn - ? [] - : ([ - { - title: t('common:business_group'), - dataIndex: 'group_id', - render: (id) => { - return _.find(busiGroups, { id })?.name; - }, - }, - ] as any), [ { title: t('note'), dataIndex: 'note', render: (data, record: any) => { + const groupName = _.find(busiGroups, { id: record.group_id })?.name; return ( - - {data} - +
+ + {data} + + {!hideBusinessGroupColumn && groupName && {groupName}} +
); }, }, + ] as any, + [ { title: t('common:datasource.id'), dataIndex: 'datasource_ids', From f06da5e52097779e6fd3f1f71bc72d72fe828432 Mon Sep 17 00:00:00 2001 From: Fiona Date: Tue, 12 May 2026 20:01:20 +0800 Subject: [PATCH 05/99] fix(alert-mutes): collapse name + datasource type + business group into Column1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per design-system-table.md §17.3: - Column1Title: 规则标题 - Column1Content: 数据源类型 + 业务组 Drop the standalone business_group and cate columns; surface them as a sub-line beneath the rule title. --- src/pages/warning/shield/index.tsx | 52 +++++++++++++----------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/src/pages/warning/shield/index.tsx b/src/pages/warning/shield/index.tsx index 771a5c63a..1e58e0c73 100644 --- a/src/pages/warning/shield/index.tsx +++ b/src/pages/warning/shield/index.tsx @@ -53,46 +53,38 @@ const Shield: React.FC = () => { const [currentShieldData, setCurrentShieldData] = useState>([]); const [loading, setLoading] = useState(false); const [datasourceIds, setDatasourceIds] = useState(); + const showBusinessGroup = !(businessGroup.isLeaf && gids !== '-2'); const columns: ColumnsType = _.concat( - businessGroup.isLeaf && gids !== '-2' - ? [] - : ([ - { - title: t('common:business_group'), - dataIndex: 'group_id', - render: (id) => { - return _.find(busiGroups, { id })?.name; - }, - }, - ] as any), [ { title: t('note'), dataIndex: 'note', render: (data, record: any) => { - return ( - - {data} - - ); - }, - }, - { - title: t('common:datasource.type'), - dataIndex: 'cate', - render: (val) => { - let logoSrc = _.find(allCates, { value: val })?.logo; - if (val === 'host') { + const groupName = _.find(busiGroups, { id: record.group_id })?.name; + let logoSrc = _.find(allCates, { value: record.cate })?.logo; + if (record.cate === 'host') { logoSrc = '/image/logos/host.png'; } - return {val}; + return ( +
+ + {data} + + + {logoSrc && {record.cate}} + {showBusinessGroup && groupName && {groupName}} + +
+ ); }, }, + ] as any, + [ { title: t('common:datasource.id'), dataIndex: 'datasource_ids', From 53afed2d82e2bf8821c231e9330b6968c876f054 Mon Sep 17 00:00:00 2001 From: Fiona Date: Tue, 12 May 2026 20:02:01 +0800 Subject: [PATCH 06/99] fix(job-tpls): collapse title + ID + business group into Column1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per design-system-table.md §17.3: - Column1Title: 标题 - Column1Content: ID + 业务组 --- src/pages/taskTpl/index.tsx | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/pages/taskTpl/index.tsx b/src/pages/taskTpl/index.tsx index fc74e0b78..f90739591 100644 --- a/src/pages/taskTpl/index.tsx +++ b/src/pages/taskTpl/index.tsx @@ -106,31 +106,27 @@ const index = (_props: any) => { } } + const showBusinessGroup = !(businessGroup.isLeaf && gids !== '-2'); const columns: ColumnProps[] = _.concat( - businessGroup.isLeaf && gids !== '-2' - ? [] - : ([ - { - title: t('common:business_group'), - dataIndex: 'group_id', - width: 100, - render: (id) => { - return _.find(busiGroups, { id })?.name; - }, - }, - ] as any), [ - { - title: 'ID', - dataIndex: 'id', - }, { title: t('tpl.title'), dataIndex: 'title', render: (text, record) => { - return {text}; + const groupName = _.find(busiGroups, { id: record.group_id })?.name; + return ( +
+ {text} + + ID: {record.id} + {showBusinessGroup && groupName && {groupName}} + +
+ ); }, }, + ] as any, + [ { title: t('tpl.tags'), dataIndex: 'tags', From efa0f94044cebf16ed292e6aa6938f7118cf2497 Mon Sep 17 00:00:00 2001 From: Fiona Date: Tue, 12 May 2026 20:02:56 +0800 Subject: [PATCH 07/99] fix(job-tasks): collapse title + ID + business group into Column1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per design-system-table.md §17.3: - Column1Title: 标题 - Column1Content: ID + 业务组 --- src/pages/task/index.tsx | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/pages/task/index.tsx b/src/pages/task/index.tsx index fb93eed8e..5219017e1 100644 --- a/src/pages/task/index.tsx +++ b/src/pages/task/index.tsx @@ -74,33 +74,28 @@ const index = (_props: any) => { refreshDeps: [gids, query, mine, days, refreshFlag], defaultPageSize: pagination.pageSize, }); + const showBusinessGroup = !(businessGroup.isLeaf && gids !== '-2'); const columns: ColumnProps[] = _.concat( - businessGroup.isLeaf && gids !== '-2' - ? [] - : ([ - { - title: t('common:business_group'), - dataIndex: 'group_id', - width: 100, - render: (id) => { - return _.find(busiGroups, { id })?.name; - }, - }, - ] as any), [ - { - title: 'ID', - dataIndex: 'id', - width: 100, - }, { title: t('task.title'), dataIndex: 'title', - width: 200, + width: 240, render: (text, record) => { - return {text}; + const groupName = _.find(busiGroups, { id: record.group_id })?.name; + return ( +
+ {text} + + ID: {record.id} + {showBusinessGroup && groupName && {groupName}} + +
+ ); }, }, + ] as any, + [ { title: t('table.operations'), width: 150, From 3d661d86a03d04a3f7495ec29198c154d12a2102 Mon Sep 17 00:00:00 2001 From: Fiona Date: Tue, 12 May 2026 20:03:48 +0800 Subject: [PATCH 08/99] fix(users): collapse identity columns into Column1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per design-system-table.md §17.3: - Column1Title: 用户名 - Column1Content: 显示名 + 邮箱 + 手机号 Username keeps sorter; secondary identifiers shown beneath as text-soft. --- src/pages/user/users.tsx | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/pages/user/users.tsx b/src/pages/user/users.tsx index 47b1815e1..222e60270 100644 --- a/src/pages/user/users.tsx +++ b/src/pages/user/users.tsx @@ -53,22 +53,16 @@ const Resource: React.FC = () => { title: t('account:profile.username'), dataIndex: 'username', ellipsis: true, - }, - { - title: t('account:profile.nickname'), - dataIndex: 'nickname', - ellipsis: true, - render: (text: string, record) => record.nickname || '-', - }, - { - title: t('account:profile.email'), - dataIndex: 'email', - render: (text: string, record) => record.email || '-', - }, - { - title: t('account:profile.phone'), - dataIndex: 'phone', - render: (text: string, record) => record.phone || '-', + sorter: true, + render: (text: string, record) => { + const secondary = _.compact([record.nickname, record.email, record.phone]); + return ( +
+ {text} + {secondary.length > 0 && {secondary.join(' · ')}} +
+ ); + }, }, ]; const userColumns: ColumnsType = [ From f5b951ba0a420a80075515ed9dfaf766111544aa Mon Sep 17 00:00:00 2001 From: Fiona Date: Tue, 12 May 2026 20:05:08 +0800 Subject: [PATCH 09/99] fix(alert-rules): collapse name + cate + business group + severity into Column2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per design-system-table.md §17.3: - Column1: 状态 (kept as-is) - Column2Title: 名称 - Column2Content: 类型 (logo) + 业务组 + 级别 - Column3: 数据源 Drop standalone cate, group_id, severities columns; embed them under name. Trim defaultColumnsConfigs accordingly. --- src/pages/alertRules/List/ListNG.tsx | 97 ++++++++------------------ src/pages/alertRules/List/constants.ts | 14 +--- 2 files changed, 33 insertions(+), 78 deletions(-) diff --git a/src/pages/alertRules/List/ListNG.tsx b/src/pages/alertRules/List/ListNG.tsx index c4c3e6408..6a3fb4e92 100644 --- a/src/pages/alertRules/List/ListNG.tsx +++ b/src/pages/alertRules/List/ListNG.tsx @@ -110,27 +110,41 @@ export default function AlertRules(props: Props) { }, }, ], - hideBusinessGroupColumn - ? [] - : ([ - { - title: t('common:business_group'), - dataIndex: 'group_id', - render: (id) => { - return _.find(busiGroups, { id })?.name; - }, - }, - ] as any), [ { - title: t('table.cate'), - dataIndex: 'cate', - render: (val) => { - let logoSrc = _.find(allCates, { value: val })?.logo; - if (val === 'host') { + title: t('table.name'), + dataIndex: 'name', + sorter: (a, b) => { + return localeCompare(a.name, b.name); + }, + render: (data, record) => { + let logoSrc = _.find(allCates, { value: record.cate })?.logo; + if (record.cate === 'host') { logoSrc = '/image/logos/host.png'; } - return {val}; + const groupName = !hideBusinessGroupColumn ? _.find(busiGroups, { id: record.group_id })?.name : undefined; + return ( +
+ + {data} + + + {logoSrc && {record.cate}} + {groupName && {groupName}} + {_.map(record.severities, (severity) => ( + + S{severity} + + ))} + +
+ ); }, }, { @@ -153,55 +167,6 @@ export default function AlertRules(props: Props) { ); }, }, - { - title: t('table.name'), - dataIndex: 'name', - sorter: (a, b) => { - return localeCompare(a.name, b.name); - }, - render: (data, record) => { - return ( - - {data} - - ); - }, - }, - { - title: t('table.severity'), - dataIndex: 'severities', - render: (data) => { - return ( -
- {_.map(data, (severity) => { - return ( - - S{severity} - - ); - })} -
- ); - }, - }, { title: t('table.append_tags'), dataIndex: 'append_tags', diff --git a/src/pages/alertRules/List/constants.ts b/src/pages/alertRules/List/constants.ts index dac1b27d8..38ad22f79 100644 --- a/src/pages/alertRules/List/constants.ts +++ b/src/pages/alertRules/List/constants.ts @@ -24,24 +24,14 @@ export const defaultColumnsConfigs = [ i18nKey: 'table.status', visible: true, }, - { - name: 'cate', - i18nKey: 'table.cate', - visible: true, - }, - { - name: 'datasource_ids', - i18nKey: 'table.datasource_ids', - visible: false, - }, { name: 'name', i18nKey: 'table.name', visible: true, }, { - name: 'severities', - i18nKey: 'table.severity', + name: 'datasource_ids', + i18nKey: 'table.datasource_ids', visible: false, }, { From 69be9a3f34f59b4b38ad6524eb4cd40ef29e6776 Mon Sep 17 00:00:00 2001 From: Fiona Date: Wed, 13 May 2026 10:11:28 +0800 Subject: [PATCH 10/99] fix(table): consolidate row actions into overflow menus --- src/pages/alertRules/List/ListNG.tsx | 87 +++++++++++++------------ src/pages/task/index.tsx | 25 +++++--- src/pages/taskTpl/index.tsx | 66 ++++++++++++------- src/pages/warning/shield/index.tsx | 96 +++++++++++++++------------- src/theme/default.less | 24 +++++++ 5 files changed, 180 insertions(+), 118 deletions(-) diff --git a/src/pages/alertRules/List/ListNG.tsx b/src/pages/alertRules/List/ListNG.tsx index 6a3fb4e92..a61a49e18 100644 --- a/src/pages/alertRules/List/ListNG.tsx +++ b/src/pages/alertRules/List/ListNG.tsx @@ -1,7 +1,7 @@ import React, { useContext, useState, useEffect } from 'react'; -import { Space, Select, Input, Button, Table, Tooltip, Tag, Modal, Switch, message } from 'antd'; +import { Space, Select, Input, Button, Table, Tooltip, Tag, Modal, Switch, message, Dropdown, Menu } from 'antd'; import { ColumnType } from 'antd/lib/table'; -import { EyeOutlined, SearchOutlined, InfoCircleOutlined, WarningFilled, CheckCircleFilled } from '@ant-design/icons'; +import { EyeOutlined, SearchOutlined, InfoCircleOutlined, WarningFilled, CheckCircleFilled, MoreOutlined } from '@ant-design/icons'; import { useTranslation } from 'react-i18next'; import { useDebounceFn } from 'ahooks'; import _ from 'lodash'; @@ -313,48 +313,55 @@ export default function AlertRules(props: Props) { { title: t('common:table.operations'), fixed: 'right', + width: 80, render: (record: any) => { const anomalyEnabled = _.get(record, ['rule_config', 'anomaly_trigger', 'enable']); return ( - - - {t('common:btn.clone')} - - - {record.cate === 'prometheus' && anomalyEnabled === true && ( -
- {t('brain_result_btn')} -
- )} -
+ onCancel() {}, + }); + }} + > + {t('common:btn.delete')} + + + + } + > + + + + } + > + + + + + + + } + > + + + + + + + } + > + - {t('executions.title')} - + + + + + + + + + + + + {t('executions.title')} + + + } + > + + + + - - + }} + > + {t('common:btn.edit')} + + + + + + + } + > + - + + + + {t('common:btn.clone')} + + + + + + + } + > + + + + + } + > + - + + + {t('common:btn.edit')} + + + + {t('common:btn.clone')} + + + + + + + } + > + + + + + + + } + > + - - { - deleteVariableConfigs(record.id).then(() => { - message.success(t('common:success.delete')); - fetchData(); - }); - }} - > - - - + + + + + + + + + + + + } + > + + + + + + + + + } + > + + + + + + + + + } + > + + + + + + + + + } + > + + + + + + + } + > + + + + } > - {t('common:btn.delete')} - + + + + } > - {t('common:btn.delete')} - + + + - + } > - + + - + } > - + + - + } > - + + - + } > - + - + - - - - {t('executions.title')} + } > - + } > - + } > - + } > - + )} + - + } > - + } > - + )} + - + } > - + )} + - + } > - + )} {!hideDeleteEventButton && ( - - - + <> + + + + deleteAlertEventsModal( + [record.id], + () => { + setRefreshFlag(_.uniqueId('refresh_')); + }, + t, + ) + } + > + {t('common:btn.delete')} + + + )} } > - + + - + } > - + } > - - + <> + + + { + Modal.confirm({ + title: t('common:confirm.delete'), + onOk() { + deletePayloads([record.id]).then(() => { + fetchData(); + fetchCates(); + }); + }, + }); + }} + > + {t('common:btn.delete')} + + + )} } > - - + <> + + + { + Modal.confirm({ + title: t('common:confirm.delete'), + onOk() { + deletePayloads([record.id]).then(() => { + fetchData(); + fetchCates(); + }); + }, + }); + }} + > + {t('common:btn.delete')} + + + )} } > - - + <> + + + { + Modal.confirm({ + title: t('common:confirm.delete'), + onOk() { + deletePayloads([record.id]).then(() => { + fetchData(); + }); + }, + }); + }} + > + {t('common:btn.delete')} + + + )} } > - + - )} + + )} } > - - + <> + + + { + Modal.confirm({ + title: t('common:confirm.delete'), + onOk() { + deleteMetrics([record.id]).then(() => { + message.success(t('common:success.delete')); + setRefreshFlag(_.uniqueId('refreshFlag_')); + }); + }, + }); + }} + > + {t('common:btn.delete')} + + + )} {record.expression_type === 'metric_name' && ( - { setNewMetricExplorerDrawerState((prev) => { return { @@ -342,13 +350,13 @@ export default function index() { }} > {t('laset_over_time')} - + )} } > - + )} {gids && gids !== '-1' && ( - + )} - + {gids !== '-1' && ( - - - + onCancel() {}, + }); + }} + > + {t('common:btn.delete')} + + + )} } > - - )} - - {record.plugin_type === 'cloudwatch' && ( - + }} + > + {record.status === 'enabled' ? t('disable') : t('enable')} + + + {record.plugin_type === 'cloudwatch' && ( + + + + )} + {record.status === 'disabled' && ( + <> + - + { + Modal.confirm({ + title: t('common:confirm.delete'), + onOk() { + deleteDataSourceById(record.id).then(() => { + message.success(t('common:success.delete')); + setRefresh((oldVal) => !oldVal); + }); + }, + }); + }} + > + {t('common:btn.delete')} + - - } - > - + + - + } > - + - + + - + } > - + + - + } > - + - + + - + } > - + } > - + } > - + } > - + )} {_.includes(perms, '/users/put') && ( handleClick(ActionType.Reset, record.id)}> - + )} + {_.includes(perms, '/users/del') && } {_.includes(perms, '/users/del') && ( { @@ -162,15 +165,15 @@ const Resource: React.FC = () => { }); }} > - + )} } > - )} + + {rightArea} {!IS_ENT && !IS_PLUS && ( - )} - From a6f0e34c42c1adc1524842a3840ac62046aadc81 Mon Sep 17 00:00:00 2001 From: Yening Qin <710leo@gmail.com> Date: Fri, 22 May 2026 10:22:56 +0800 Subject: [PATCH 77/99] feat(landing): use getRecommendByUrl for AI prompts feat(landing): use getRecommendByUrl for AI prompts --- src/pages/landing/index.tsx | 9 +++++---- src/pages/landing/landing.data.ts | 4 ++-- src/pages/landing/locale/en_US.ts | 4 ++-- src/pages/landing/locale/ja_JP.ts | 4 ++-- src/pages/landing/locale/ru_RU.ts | 4 ++-- src/pages/landing/locale/zh_CN.ts | 4 ++-- src/pages/landing/locale/zh_HK.ts | 4 ++-- 7 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/pages/landing/index.tsx b/src/pages/landing/index.tsx index ecfb98f66..b81f51992 100644 --- a/src/pages/landing/index.tsx +++ b/src/pages/landing/index.tsx @@ -37,7 +37,7 @@ import { } from 'lucide-react'; import PageLayout from '@/components/pageLayout'; import { useAiChatContext } from '@/components/AiChatNG'; -import { buildPageFrom } from '@/components/AiChatNG/recommend'; +import { buildPageFrom, getRecommendByUrl } from '@/components/AiChatNG/recommend'; import { DOC_LINKS, landingAiAssistant, @@ -107,18 +107,19 @@ function makeLinkProps(url: string | undefined, history: ReturnType { + const recommend = getRecommendByUrl('/landing', i18n.language); openAiChat({ queryPageFrom: buildPageFrom({ url: '/landing' }), - promptList: prefill ? [prefill] : [t('quickStart.ingest.links.0'), t('quickStart.observe.links.0'), t('quickStart.alert.links.0'), t('quickStart.ai.links.0')], + promptList: prefill ? [prefill] : recommend?.promptList, }); }, - [openAiChat, t], + [openAiChat, i18n.language], ); return ( diff --git a/src/pages/landing/landing.data.ts b/src/pages/landing/landing.data.ts index d3729a24f..2e9bdf055 100644 --- a/src/pages/landing/landing.data.ts +++ b/src/pages/landing/landing.data.ts @@ -137,7 +137,7 @@ export const landingQuickStartCards: LandingGuideCard[] = [ titleKey: 'quickStart.ingest.title', descriptionKey: 'quickStart.ingest.description', links: [ - { labelKey: 'quickStart.ingest.links.0', url: `${DOCS_V8_BASE}install/compose/` }, + { labelKey: 'quickStart.ingest.links.0', url: 'https://flashcat.cloud/docs/content/flashcat-monitor/categraf/2-installation/' }, { labelKey: 'quickStart.ingest.links.1', url: `${DOCS_V8_BASE}agent/categraf/` }, ], }, @@ -161,7 +161,7 @@ export const landingQuickStartCards: LandingGuideCard[] = [ titleKey: 'quickStart.ai.title', descriptionKey: 'quickStart.ai.description', links: [ - { labelKey: 'quickStart.ai.links.0', url: `${DOCS_V8_BASE}usecase/processor/` }, + { labelKey: 'quickStart.ai.links.0', url: `${DOCS_V8_BASE}usage/ai-config/builtin-skills/` }, { labelKey: 'quickStart.ai.links.1', url: `${DOCS_V8_BASE}usecase/processor/` }, ], }, diff --git a/src/pages/landing/locale/en_US.ts b/src/pages/landing/locale/en_US.ts index d65b5879d..a6146c089 100644 --- a/src/pages/landing/locale/en_US.ts +++ b/src/pages/landing/locale/en_US.ts @@ -81,7 +81,7 @@ const en_US = { ingest: { title: 'Unified Ingestion', description: 'Deploy and ingest data quickly', - links: ['How to deploy Nightingale with Docker Compose?', 'How to collect host and middleware data with Categraf?'], + links: ['How to deploy the Categraf collector?', 'How to collect host and middleware data with Categraf?'], }, observe: { title: 'Unified Observability', @@ -96,7 +96,7 @@ const en_US = { ai: { title: 'AI Intelligence', description: 'LLM and agents', - links: ['How to add a data source?', 'How to use Agents to analyze alerts?'], + links: ['What built-in skills does Nightingale have?', 'How to use Agents to analyze alerts?'], }, }, aiAssistant: { diff --git a/src/pages/landing/locale/ja_JP.ts b/src/pages/landing/locale/ja_JP.ts index 7a1586f01..5503bbdbc 100644 --- a/src/pages/landing/locale/ja_JP.ts +++ b/src/pages/landing/locale/ja_JP.ts @@ -69,7 +69,7 @@ const ja_JP = { ingest: { title: '統一取込', description: '迅速にデプロイしデータを取り込む', - links: ['Docker Compose で Nightingale をデプロイする方法は?', 'Categraf でホスト/ミドルウェアを収集する方法は?'], + links: ['Categraf コレクターをデプロイする方法は?', 'Categraf でホスト/ミドルウェアを収集する方法は?'], }, observe: { title: '統一可観測', @@ -84,7 +84,7 @@ const ja_JP = { ai: { title: 'AI インテリジェンス', description: 'LLM とエージェント', - links: ['データソースを追加するには?', 'エージェントでアラートを分析するには?'], + links: ['Nightingale にはどんな組み込みスキルがありますか?', 'エージェントでアラートを分析するには?'], }, }, aiAssistant: { diff --git a/src/pages/landing/locale/ru_RU.ts b/src/pages/landing/locale/ru_RU.ts index 8fa7f9c52..dee617325 100644 --- a/src/pages/landing/locale/ru_RU.ts +++ b/src/pages/landing/locale/ru_RU.ts @@ -69,7 +69,7 @@ const ru_RU = { ingest: { title: 'Единая ингестия', description: 'Быстрое развёртывание и подключение данных', - links: ['Как развернуть Nightingale через Docker Compose?', 'Как собирать данные хостов через Categraf?'], + links: ['Как развернуть коллектор Categraf?', 'Как собирать данные хостов через Categraf?'], }, observe: { title: 'Единая наблюдаемость', @@ -84,7 +84,7 @@ const ru_RU = { ai: { title: 'AI-интеллект', description: 'LLM и агенты', - links: ['Как добавить источник данных?', 'Как использовать агентов для анализа алертов?'], + links: ['Какие встроенные навыки есть у Nightingale?', 'Как использовать агентов для анализа алертов?'], }, }, aiAssistant: { diff --git a/src/pages/landing/locale/zh_CN.ts b/src/pages/landing/locale/zh_CN.ts index 5b1fefa68..6f6318211 100644 --- a/src/pages/landing/locale/zh_CN.ts +++ b/src/pages/landing/locale/zh_CN.ts @@ -81,7 +81,7 @@ const zh_CN = { ingest: { title: '统一接入', description: '快速完成部署与数据接入', - links: ['如何使用 Docker Compose 快速部署 Nightingale?', '如何用 Categraf 采集主机和中间件数据?'], + links: ['如何部署 Categraf 采集器?', '如何用 Categraf 采集主机和中间件数据?'], }, observe: { title: '统一观测', @@ -96,7 +96,7 @@ const zh_CN = { ai: { title: 'AI 智能化', description: '大模型与智能体', - links: ['如何添加数据源?', '如何使用 Agent 自动分析告警?'], + links: ['夜莺有哪些内置技能?', '如何使用 Agent 自动分析告警?'], }, }, aiAssistant: { diff --git a/src/pages/landing/locale/zh_HK.ts b/src/pages/landing/locale/zh_HK.ts index ef9fd4fcf..acbd4e5ab 100644 --- a/src/pages/landing/locale/zh_HK.ts +++ b/src/pages/landing/locale/zh_HK.ts @@ -69,7 +69,7 @@ const zh_HK = { ingest: { title: '統一接入', description: '快速完成部署與數據接入', - links: ['如何使用 Docker Compose 快速部署 Nightingale?', '如何用 Categraf 採集主機和中間件數據?'], + links: ['如何部署 Categraf 採集器?', '如何用 Categraf 採集主機和中間件數據?'], }, observe: { title: '統一觀測', @@ -84,7 +84,7 @@ const zh_HK = { ai: { title: 'AI 智慧化', description: '大模型與智慧體', - links: ['如何添加數據源?', '如何使用 Agent 自動分析告警?'], + links: ['夜鶯有哪些內置技能?', '如何使用 Agent 自動分析告警?'], }, }, aiAssistant: { From b1680d1b5d0bc7957903d484545588a65506d110 Mon Sep 17 00:00:00 2001 From: jsers Date: Fri, 22 May 2026 10:26:24 +0800 Subject: [PATCH 78/99] fix(alert-rules): filter out annotation_qd from processor type select options --- src/pages/alertRules/Form/PipelineConfigsNG/Processor.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/alertRules/Form/PipelineConfigsNG/Processor.tsx b/src/pages/alertRules/Form/PipelineConfigsNG/Processor.tsx index 49ded05ce..2220c33e9 100644 --- a/src/pages/alertRules/Form/PipelineConfigsNG/Processor.tsx +++ b/src/pages/alertRules/Form/PipelineConfigsNG/Processor.tsx @@ -110,7 +110,7 @@ export default function Processor(props: Props) { } > diff --git a/src/plugins/elasticsearch/AlertRule/Queries/Query.tsx b/src/plugins/elasticsearch/AlertRule/Queries/Query.tsx index 0fbbe69b1..9b4b245df 100644 --- a/src/plugins/elasticsearch/AlertRule/Queries/Query.tsx +++ b/src/plugins/elasticsearch/AlertRule/Queries/Query.tsx @@ -153,7 +153,7 @@ export default function Query(props: Props) { } - labelWidth={90} + addonAfter='Lucene' > From b9a318a557d5cf49edb5ce0411fa0bc31b440c4a Mon Sep 17 00:00:00 2001 From: Fiona Date: Fri, 22 May 2026 11:12:24 +0800 Subject: [PATCH 81/99] fix(side-menu): refine bottom menu behavior --- src/components/SideMenu/MenuList.tsx | 10 ++++++++-- src/components/SideMenu/menu.less | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/components/SideMenu/MenuList.tsx b/src/components/SideMenu/MenuList.tsx index c6b9817c1..1c813d862 100644 --- a/src/components/SideMenu/MenuList.tsx +++ b/src/components/SideMenu/MenuList.tsx @@ -143,6 +143,7 @@ function SectionHeader(props: { section: NonNullable; coll export function MenuGroup(props: { item: IMenuItem } & IMenuProps) { const { t } = useTranslation('sideMenu'); const { item, collapsed, selectedKeys, sideMenuBgColor, isLight, ...otherProps } = props; + const rootRef = useRef(null); const isBlueTheme = localStorage.getItem('n9e-dark-mode') === '3'; const isActive = isMenuGroupActive(item, selectedKeys); const [isExpand, setIsExpand] = useState(false); @@ -181,7 +182,7 @@ export function MenuGroup(props: { item: IMenuItem } & IMenuProps) { const submenuOpen = isExpand && !collapsed && visibleChildren.length > 0; return ( -
+
{ if (collapsed) { @@ -209,6 +210,11 @@ export function MenuGroup(props: { item: IMenuItem } & IMenuProps) { style={{ height: !isExpand || collapsed ? 0 : visibleChildren.length * 30, }} + onTransitionEnd={(e) => { + if (e.propertyName === 'height' && submenuOpen) { + rootRef.current?.scrollIntoView({ block: 'nearest' }); + } + }} >
-
+
{IS_ENT ? ( Date: Fri, 22 May 2026 11:51:55 +0800 Subject: [PATCH 82/99] feat(pages): add doc links to PageLayout across 17 pages Add documentation URL prop to PageLayout component for AI config, alerting, event pipeline, explorer, hosts, integrations, metrics, notification, recording rules, and task pages. --- src/pages/aiConfig/llmConfigs/pages/List.tsx | 2 +- src/pages/aiConfig/skills/pages/List.tsx | 6 +++--- src/pages/alertCurEvent/pages/List/index.tsx | 7 ++----- src/pages/alertRules/index.tsx | 2 +- src/pages/builtInComponents/List.tsx | 2 +- src/pages/datasource/index.tsx | 2 +- src/pages/embeddedProduct/pages/List/index.tsx | 11 ++--------- src/pages/eventPipeline/pages/Executions/index.tsx | 2 +- src/pages/eventPipeline/pages/ListWithPageLayout.tsx | 2 +- src/pages/explorer/Log.tsx | 2 +- src/pages/hosts/pages/List/index.tsx | 2 +- src/pages/logExplorer/index.tsx | 1 + src/pages/metricsBuiltin/List.tsx | 6 +++++- src/pages/notificationChannels/pages/ListNG/index.tsx | 6 +++++- src/pages/notificationTemplates/pages/List/index.tsx | 6 +++++- src/pages/recordingRules/index.tsx | 2 +- src/pages/task/add.tsx | 1 + 17 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/pages/aiConfig/llmConfigs/pages/List.tsx b/src/pages/aiConfig/llmConfigs/pages/List.tsx index d047311fe..6ab0bb050 100644 --- a/src/pages/aiConfig/llmConfigs/pages/List.tsx +++ b/src/pages/aiConfig/llmConfigs/pages/List.tsx @@ -22,7 +22,7 @@ export default function List() { return ( <> - +
diff --git a/src/pages/aiConfig/skills/pages/List.tsx b/src/pages/aiConfig/skills/pages/List.tsx index 6b36a1e4e..73934ae89 100644 --- a/src/pages/aiConfig/skills/pages/List.tsx +++ b/src/pages/aiConfig/skills/pages/List.tsx @@ -251,7 +251,7 @@ export default function List() { if (_.isEmpty(data)) { if (loading) { return ( - +
@@ -263,7 +263,7 @@ export default function List() { return ( <> - +
- +
diff --git a/src/pages/alertCurEvent/pages/List/index.tsx b/src/pages/alertCurEvent/pages/List/index.tsx index 3cc49d98c..153a6f0c7 100644 --- a/src/pages/alertCurEvent/pages/List/index.tsx +++ b/src/pages/alertCurEvent/pages/List/index.tsx @@ -133,10 +133,7 @@ const AlertCurEvent: React.FC = () => { return requestParams; }, [filter.aggr_rule_id, JSON.stringify(params)]); - const { - refresh: reloadRuleCards, - data: ruleCardsData, - } = useRequest( + const { refresh: reloadRuleCards, data: ruleCardsData } = useRequest( () => { // ready 会保证这里不会在 undefined 时执行 return getAlertCards(ruleCardsRequestParams as RuleCardsRequestParams); @@ -188,7 +185,7 @@ const AlertCurEvent: React.FC = () => { }, [JSON.stringify(filter)]); return ( - } title={t('title')}> + } title={t('title')} doc='https://flashcat.cloud/docs/content/flashcat-monitor/nightingale-v9/usage/alert-notify/events/cur-events/'>
diff --git a/src/pages/alertRules/index.tsx b/src/pages/alertRules/index.tsx index fb98df71a..c7cc22525 100644 --- a/src/pages/alertRules/index.tsx +++ b/src/pages/alertRules/index.tsx @@ -37,7 +37,7 @@ export default function index() { const [gids, setGids] = useState(getDefaultGids(N9E_GIDS_LOCALKEY, businessGroup)); return ( - }> + } doc='https://flashcat.cloud/docs/content/flashcat-monitor/nightingale-v9/usage/alert-notify/rules/alert-rules/'>
{businessGroup.ids ? : } diff --git a/src/pages/builtInComponents/List.tsx b/src/pages/builtInComponents/List.tsx index c369efedc..4b23fbeba 100644 --- a/src/pages/builtInComponents/List.tsx +++ b/src/pages/builtInComponents/List.tsx @@ -55,7 +55,7 @@ export default function index() { }, []); return ( - }> + } doc='https://flashcat.cloud/docs/content/flashcat-monitor/nightingale-v9/usage/integrations/templates/'>
diff --git a/src/pages/datasource/index.tsx b/src/pages/datasource/index.tsx index 73ebad2ea..e19486713 100644 --- a/src/pages/datasource/index.tsx +++ b/src/pages/datasource/index.tsx @@ -41,7 +41,7 @@ export default function index() { }, []); return ( - +
+