Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
af54534
feat(table): minimal EnhancedTable (薄透传 + 声明式行操作) + 迁移 taskTpl 验证
Fiona2016 Jun 1, 2026
913cd33
feat(table): 对齐 taskTpl 至 0517 设计(Tags + 列聚合)+ EnhancedTable 操作列
Fiona2016 Jun 1, 2026
9617122
feat(table): 列工厂助手 tagsColumn/userColumn/dateColumn(可与手写列混用)
Fiona2016 Jun 1, 2026
66f987d
docs(table): English comments in EnhancedTable, trimmed to essentials
Fiona2016 Jun 1, 2026
6f31321
feat(table): kebab menu items support leading icon (align 0517)
Fiona2016 Jun 1, 2026
e4185bd
fix(table): job-tpls card overflow + left-align action column
Fiona2016 Jun 1, 2026
f570d5e
feat(table): migrate alert-mutes (shield) to EnhancedTable
Fiona2016 Jun 1, 2026
f19c4f8
feat(table): restore global theme/table.less baseline from 0517
Fiona2016 Jun 1, 2026
27c8f10
fix(table): trim theme/table.less to fixed-column fix only; revert gl…
Fiona2016 Jun 1, 2026
251a552
fix(table): render alert-mutes tags column with Tags pills (align 0517)
Fiona2016 Jun 1, 2026
366d45c
feat(table): migrate alert-rules list to EnhancedTable (align 0517)
Fiona2016 Jun 1, 2026
1c3f1c0
feat(table): design-system sort-column icon, scoped to .fc-enhanced-t…
Fiona2016 Jun 1, 2026
d91ee74
fix(table): align scoped sort icon to design-system preview
Fiona2016 Jun 1, 2026
fb1d158
fix(table): add header-cell hover/sorted background (align design-sys…
Fiona2016 Jun 1, 2026
03ee18d
fix(table): header hover bg on ALL columns; no extra bg on sorted column
Fiona2016 Jun 1, 2026
f2cd814
feat(table): sorted column header gets a background via token
Fiona2016 Jun 1, 2026
f0dd0e6
feat(table): migrate event-pipelines list to EnhancedTable (align 0517)
Fiona2016 Jun 1, 2026
e02f955
feat(table): add EllipsisText component; truncate event-pipelines not…
Fiona2016 Jun 1, 2026
14c0ef0
style(table): white-surface tooltip for EllipsisText via design tokens
Fiona2016 Jun 1, 2026
4afb66b
feat(table): migrate datasource list to EnhancedTable (align 0517)
Fiona2016 Jun 1, 2026
8f8fb8e
style(table): consistent sorted-column bg + design-system filter funnel
Fiona2016 Jun 1, 2026
e2596de
feat(table): migrate remaining 30 fe list tables to EnhancedTable (al…
Fiona2016 Jun 1, 2026
f2c4c80
fix(table): RowAction.tooltip; fix disabled-delete styling (node hack)
Fiona2016 Jun 2, 2026
c32196a
fix(table): consistent switch size + Metrics clone/edit menu styling
Fiona2016 Jun 2, 2026
dfcc6f6
feat(alert-cur-events): restore 0517 event-tags expand/collapse
Fiona2016 Jun 2, 2026
8b3a4f3
style(table): fix sort-arrow hover pill + icon crispness
Fiona2016 Jun 2, 2026
1f9d17e
style(table): keep short CJK column titles on one line; tighten sort+…
Fiona2016 Jun 3, 2026
a859990
feat(TableTags): 支持 maxCount 固定展示数量;告警事件改用公共 Tags 组件
Fiona2016 Jun 3, 2026
a96cab1
告警历史事件标签对齐告警事件:公共Tags组件(+N弹层/复制)+展开收起切换
Fiona2016 Jun 3, 2026
a64aef9
Merge remote-tracking branch 'origin/main' into feat-table-design-0601
Fiona2016 Jun 4, 2026
a8b1999
fix(event-pipelines): stop infinite column squeeze on narrow viewport
Fiona2016 Jun 4, 2026
409d7ef
Merge remote-tracking branch 'origin/main' into feat-table-design-0601
Fiona2016 Jun 5, 2026
7f12bca
Merge remote-tracking branch 'origin/main' into feat-table-design-0601
Fiona2016 Jun 9, 2026
c6ac5a2
Merge remote-tracking branch 'origin/main' into feat-table-design-0601
Fiona2016 Jun 10, 2026
fd26da4
refactor: 展示列组件,同步
guguji5 Jun 11, 2026
d8a5e34
统一启用列表格文案与筛选
Fiona2016 Jun 13, 2026
47c6e5e
Merge pull request #2129 from n9e/feat/table-enable-column-standardiz…
Fiona2016 Jun 13, 2026
8dd28a5
抽取启用状态列表格配置
Fiona2016 Jun 13, 2026
c66aa9f
Merge pull request #2130 from n9e/feat/table-enable-column-helper-0613
Fiona2016 Jun 13, 2026
d3dfe6d
feat: support enhanced table update-by filters
Fiona2016 Jun 13, 2026
5ee34ed
Merge branch 'feat-table-design-0601' into feat/update-by-filter-0613…
Fiona2016 Jun 13, 2026
1e6cb0d
Merge pull request #2132 from n9e/feat/update-by-filter-0613-clean
Fiona2016 Jun 13, 2026
253c86d
feat: render inline table actions as icons
Fiona2016 Jun 13, 2026
6eda166
Merge pull request #2133 from n9e/feat/table-inline-action-icons-0613
Fiona2016 Jun 13, 2026
7bb33ef
style: refine inline table action icons
Fiona2016 Jun 14, 2026
6f3564e
Merge branch 'feat/table-inline-action-icons-0613' into feat-table-de…
Fiona2016 Jun 14, 2026
993f4fd
refactor(EnhancedTable): simplify column render functions
jsers Jun 15, 2026
5319418
feat(TableTags): add popoverTitle prop and refine popover layout
jsers Jun 15, 2026
d013f2e
feat(TableTags): add hideLabel prop and sort alert rule severities
jsers Jun 15, 2026
b47c7bf
feat(EnhancedTable): move sorter into dateColumn and cleanup dashboar…
jsers Jun 15, 2026
2334f11
refactor(EnhancedTable): remove tagsColumn default width and simplify…
jsers Jun 15, 2026
f69bb32
refactor: 补了一个居中对齐的样式
guguji5 Jun 16, 2026
459a4d9
Adjust notification channel table widths
Fiona2016 Jun 16, 2026
0f2e1cd
Synchronize EnhancedTable component
star-6 Jun 16, 2026
ea9e7c4
Merge origin/main into feat-table-design-0601
Fiona2016 Jun 16, 2026
8f996ab
refactor(task): re-migrate task result + tpl tables to EnhancedTable
Fiona2016 Jun 16, 2026
dfa4c2d
fix(table): prevent drag helper fixed-column misalignment
Fiona2016 Jun 16, 2026
4489a60
fix: align alert event unclaim action menu
Fiona2016 Jun 16, 2026
93d9e31
feat(table): dateColumn 默认单行(可配 multiline 两行);拖拽行隐藏操作按钮
Fiona2016 Jun 16, 2026
1617f45
feat(EnhancedTable): 新增 offline 行操作图标(ArrowDownToLine) 供下线类操作使用
Fiona2016 Jun 17, 2026
2526d5c
fix(servers): controlled sort to keep rowSpan in sync + migrate to En…
Fiona2016 Jun 17, 2026
3c94241
fix(embeddedProduct): unfix action column so ⋮ doesn't detach during …
Fiona2016 Jun 17, 2026
112432b
fix(targets): 机器列表标签列改用共享 Tags 组件
Fiona2016 Jun 17, 2026
7ed9e11
feat(table): EnhancedTable 加 compactHeader(与 srm-fe 对齐)
Fiona2016 Jun 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 63 additions & 63 deletions src/components/Contacts/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { useState, useEffect } from 'react';
import { Drawer, Table, Switch, Space, Button, Modal, message } from 'antd';
import { Drawer, Switch, Space, Button, Modal, message } from 'antd';
import { useTranslation } from 'react-i18next';
import _ from 'lodash';
import { CloseOutlined } from '@ant-design/icons';

import EnhancedTable, { getEnabledStatusColumn } from '@/components/EnhancedTable';
import { getNotifyContacts, putNotifyContacts } from './services';
import { ContactType } from './types';
import { NS, CN } from './constants';
Expand Down Expand Up @@ -51,11 +52,61 @@ export default function ContactDrawer(props: Props) {
</Button>
</Space>
</div>
<Table<ContactType>
<EnhancedTable<ContactType>
rowKey='ident'
size='small'
pagination={false}
dataSource={data}
rowActions={(reocrd) => ({
menu: _.compact([
{
key: 'edit',
icon: 'edit',
text: t('common:btn.edit'),
onClick: () => {
EditModal({
initialValues: reocrd,
onOk: (values) => {
const oldIndex = _.findIndex(data, (item) => item.ident === reocrd.ident);
const newData = _.map(data, (item, idx) => {
if (idx === oldIndex) {
return values;
}
return item;
});
putNotifyContacts(newData).then(() => {
setData(newData);
message.success(t('common:success.edit'));
});
},
});
},
},
!reocrd.built_in
? {
key: 'delete',
icon: 'delete',
text: t('common:btn.delete'),
danger: true,
onClick: () => {
Modal.confirm({
title: t('common:confirm.delete'),
onOk: () => {
const newData = _.filter(data, (item) => item.ident !== reocrd.ident);
putNotifyContacts(newData).then(() => {
setData(newData);
message.success(t('common:success.delete'));
});
},

onCancel() {},
});
},
}
: undefined,
]),
})}
actionColumn={{ title: t('common:table.operations'), width: 64 }}
columns={[
{
title: t('common:table.name'),
Expand All @@ -68,9 +119,16 @@ export default function ContactDrawer(props: Props) {
key: 'ident',
},
{
title: t('common:table.enabled'),
dataIndex: 'hide',
...getEnabledStatusColumn({
title: t('common:table.enabled'),
dataIndex: 'hide',
enabledText: t('common:table.enabled'),
disabledText: t('disabled'),
enabledValue: false,
disabledValue: true,
}),
key: 'hide',

render: (val: boolean, record) => {
return (
<Switch
Expand All @@ -95,66 +153,8 @@ export default function ContactDrawer(props: Props) {
);
},
},
{
title: t('common:table.operations'),
width: 100,
render: (reocrd) => {
return (
<Space>
<a
onClick={() => {
EditModal({
initialValues: reocrd,
onOk: (values) => {
const oldIndex = _.findIndex(data, (item) => item.ident === reocrd.ident);
const newData = _.map(data, (item, idx) => {
if (idx === oldIndex) {
return values;
}
return item;
});
putNotifyContacts(newData).then(() => {
setData(newData);
message.success(t('common:success.edit'));
});
},
});
}}
>
{t('common:btn.edit')}
</a>
{!reocrd.built_in && (
<Button
size='small'
type='link'
danger
style={{
padding: 0,
}}
onClick={() => {
Modal.confirm({
title: t('common:confirm.delete'),
onOk: () => {
const newData = _.filter(data, (item) => item.ident !== reocrd.ident);
putNotifyContacts(newData).then(() => {
setData(newData);
message.success(t('common:success.delete'));
});
},

onCancel() {},
});
}}
>
{t('common:btn.delete')}
</Button>
)}
</Space>
);
},
},
]}
></Table>
></EnhancedTable>
</div>
</div>
</Drawer>
Expand Down
60 changes: 60 additions & 0 deletions src/components/EllipsisText/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useRef, useState } from 'react';
import { Tooltip } from 'antd';
import type { TooltipProps } from 'antd';
import classNames from 'classnames';

export interface EllipsisTextProps {
/** content to render, truncated to a single line */
text: React.ReactNode;
/** tooltip content when truncated; defaults to `text` */
title?: React.ReactNode;
className?: string;
style?: React.CSSProperties;
/** extra props forwarded to the underlying Tooltip */
tooltipProps?: Partial<TooltipProps>;
}

const ellipsisStyle: React.CSSProperties = {
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
};

/**
* Single-line text that truncates with an ellipsis when it overflows its
* container, revealing the full content in a tooltip on hover — but only when
* it is actually truncated. The tooltip is controlled and overflow is measured
* lazily on hover, so it stays cheap when rendered across many table rows.
*
* Relies on the container having a bounded width (e.g. a fixed-layout table
* cell, which antd uses whenever a column is fixed/has ellipsis/scroll).
*/
export default function EllipsisText({ text, title, className, style, tooltipProps }: EllipsisTextProps) {
const ref = useRef<HTMLDivElement>(null);
const [visible, setVisible] = useState(false);

const onVisibleChange = (open: boolean) => {
if (!open) {
setVisible(false);
return;
}
const el = ref.current;
setVisible(!!el && el.scrollWidth > el.clientWidth);
};

return (
<Tooltip
title={title ?? text}
visible={visible}
onVisibleChange={onVisibleChange}
// light surface tooltip via design tokens; auto-flips to a dark surface in dark mode
color='var(--fc-fill-2)'
overlayInnerStyle={{ color: 'var(--fc-text-1)', border: '1px solid var(--fc-border-color)' }}
{...tooltipProps}
>
<div ref={ref} className={classNames('fc-ellipsis-text', className)} style={{ ...ellipsisStyle, ...style }}>
{text}
</div>
</Tooltip>
);
}
66 changes: 66 additions & 0 deletions src/components/EnhancedTable/EnhancedTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { useMemo, useRef } from 'react';
import { Table } from 'antd';
import type { ColumnType, ColumnsType } from 'antd/lib/table';
import classNames from 'classnames';

import { injectColumnFilters } from './columns';
import { RowActionCell } from './RowActionCell';
import type { EnhancedTableProps } from './types';
import './style.less';
import { defaultComparator } from './sorter';

/**
* Thin pass-through wrapper over antd Table.
* Forwards all TableProps; pass `rowActions` to auto-render the action column.
* Visual baseline (sort/filter icons, fixed-column bg, …) lives in global theme/table.less.
*
* NOTE: keep this file exporting ONLY the component, otherwise React Fast Refresh
* loses its boundary here and edits trigger a full page reload.
*/
export default function EnhancedTable<RecordType extends object = any>(props: EnhancedTableProps<RecordType>) {
const { rowActions, actionColumn, columns, className, dataSource, compactHeader, ...rest } = props;

const rowActionsRef = useRef(rowActions);
rowActionsRef.current = rowActions;
const hasRowActions = !!rowActions;

const enhancedColumns: ColumnsType<RecordType> = useMemo(() => {
let finalColumns: ColumnsType<RecordType> | undefined = injectColumnFilters(columns, Array.isArray(dataSource) ? dataSource : undefined);
const allColumns: ColumnType<RecordType>[] = ((finalColumns ?? []) as ColumnsType<RecordType>).filter(Boolean).map((col: ColumnType<RecordType>) => {
const dataIndex = col.dataIndex;
// 操作列不排序
const sorter = col.sorter !== undefined ? col.sorter : !!dataIndex && !['operate'].includes(dataIndex as string) ? defaultComparator(dataIndex as string) : false;
return {
...col,
// ellipsis: col.ellipsis !== undefined ? col.ellipsis : true,
sorter,
};
});

if (hasRowActions) {
const opColumn: ColumnType<RecordType> = {
title: '操作',
key: '__fc_action__',
fixed: 'right',
width: 100,
...actionColumn,
render: (_value: unknown, record: RecordType, index: number) => {
const cfg = rowActionsRef.current?.(record, index);
return cfg ? <RowActionCell actions={cfg} /> : null;
},
};
allColumns.push(opColumn);
}

return allColumns;
}, [columns, actionColumn, hasRowActions]);

return (
<Table<RecordType>
{...rest}
dataSource={dataSource}
columns={enhancedColumns}
className={classNames('fc-enhanced-table', { 'fc-enhanced-table--compact-header': compactHeader }, className)}
/>
);
}
Loading