refine Semi UI alert workspace

This commit is contained in:
lingniu
2026-07-18 14:12:44 +08:00
parent 32c8939eb5
commit 01d165d771
4 changed files with 70 additions and 2 deletions

View File

@@ -132,6 +132,9 @@ test('clears old alert rows and inspector evidence when the event scope changes'
expect(view.container.querySelector(`.${className}.semi-card`)).toBeInTheDocument(); expect(view.container.querySelector(`.${className}.semi-card`)).toBeInTheDocument();
} }
expect(view.container.querySelector('.v2-alert-navigation')).toBeInTheDocument(); expect(view.container.querySelector('.v2-alert-navigation')).toBeInTheDocument();
expect(screen.getByLabelText('告警中心工作区')).toHaveClass('v2-workspace-command-bar', 'v2-alert-command-bar');
expect(screen.getByRole('heading', { level: 5, name: '告警处置工作台' })).toBeInTheDocument();
expect(screen.getByText('核验事件证据、治理规则并追踪通知状态')).toBeInTheDocument();
expect(screen.getByText('可处置事件')).toBeInTheDocument(); expect(screen.getByText('可处置事件')).toBeInTheDocument();
expect(screen.queryByRole('heading', { level: 2, name: '告警中心' })).not.toBeInTheDocument(); expect(screen.queryByRole('heading', { level: 2, name: '告警中心' })).not.toBeInTheDocument();
expect(view.container.querySelector('.v2-alert-inspector')).not.toBeInTheDocument(); expect(view.container.querySelector('.v2-alert-inspector')).not.toBeInTheDocument();

View File

@@ -10,6 +10,7 @@ import { InlineError, PanelEmpty, PanelLoading } from '../shared/AsyncState';
import { MetricActionButton } from '../shared/MetricActionButton'; import { MetricActionButton } from '../shared/MetricActionButton';
import { SegmentedTabs } from '../shared/SegmentedTabs'; import { SegmentedTabs } from '../shared/SegmentedTabs';
import { TablePagination } from '../shared/TablePagination'; import { TablePagination } from '../shared/TablePagination';
import { WorkspaceCommandBar } from '../shared/WorkspaceCommandBar';
import { WorkspacePanelHeader } from '../shared/WorkspacePanelHeader'; import { WorkspacePanelHeader } from '../shared/WorkspacePanelHeader';
import { WorkspaceFilterPanel } from '../shared/WorkspaceFilterPanel'; import { WorkspaceFilterPanel } from '../shared/WorkspaceFilterPanel';
import { detailTriggerRow } from '../shared/detailTriggerRow'; import { detailTriggerRow } from '../shared/detailTriggerRow';
@@ -443,5 +444,23 @@ export default function AlertsPage() {
const setTab = (next: Tab) => { setTabState(next); const copy = new URLSearchParams(params); copy.set('tab', next); setParams(copy, { replace: true }); }; const setTab = (next: Tab) => { setTabState(next); const copy = new URLSearchParams(params); copy.set('tab', next); setParams(copy, { replace: true }); };
const setFilters = (next: Filters) => { setFilterState(next); const copy = new URLSearchParams(); if (tab !== 'events') copy.set('tab', tab); Object.entries(next).forEach(([key, value]) => { if (value) copy.set(key, value); }); setParams(copy, { replace: true }); }; const setFilters = (next: Filters) => { setFilterState(next); const copy = new URLSearchParams(); if (tab !== 'events') copy.set('tab', tab); Object.entries(next).forEach(([key, value]) => { if (value) copy.set(key, value); }); setParams(copy, { replace: true }); };
const tabs = [{ key: 'events' as const, label: '告警事件', icon: <IconAlarm /> }, ...(admin ? [{ key: 'rules' as const, label: '规则配置', icon: <IconSetting /> }] : []), { key: 'notifications' as const, label: '站内通知', icon: <IconBell />, count: unread || undefined }]; const tabs = [{ key: 'events' as const, label: '告警事件', icon: <IconAlarm /> }, ...(admin ? [{ key: 'rules' as const, label: '规则配置', icon: <IconSetting /> }] : []), { key: 'notifications' as const, label: '站内通知', icon: <IconBell />, count: unread || undefined }];
return <div className={`v2-alert-page is-${activeTab}`}><div className="v2-alert-navigation"><SegmentedTabs className="v2-alert-tabs" variant="filled" ariaLabel="告警中心分类" value={activeTab} items={tabs} onChange={setTab} /><div className="v2-alert-navigation-meta"><Typography.Text type="tertiary">{operator ? '可处置事件' : '只读查看'}</Typography.Text><Tag color={unread ? 'orange' : 'green'} type="light" size="small">{unread ? `${unread.toLocaleString('zh-CN')} 条未读` : '通知已读'}</Tag></div></div>{activeTab !== 'notifications' && rules.isError ? <InlineError message={rules.error.message} onRetry={() => rules.refetch()} /> : null}{activeTab === 'rules' && metrics.isError ? <InlineError message={metrics.error.message} onRetry={() => metrics.refetch()} /> : null}{activeTab === 'events' ? <EventWorkspace filters={filters} draft={eventDraft} setDraft={setEventDraft} setFilters={setFilters} rules={rules.data ?? []} unread={unread} editable={operator} onTab={setTab} /> : activeTab === 'rules' ? <RulesWorkspace rules={rules.data ?? []} metrics={metrics.data?.metrics ?? []} /> : <NotificationsWorkspace editable={operator} />}</div>; return <div className={`v2-alert-page is-${activeTab}`}>
<WorkspaceCommandBar
className="v2-alert-navigation v2-alert-command-bar"
ariaLabel="告警中心工作区"
title="告警处置工作台"
description="核验事件证据、治理规则并追踪通知状态"
status={unread ? `${unread.toLocaleString('zh-CN')} 条未读` : '通知已读'}
statusColor={unread ? 'orange' : 'green'}
meta={<Typography.Text type="tertiary">{operator ? '可处置事件' : '只读查看'}</Typography.Text>}
actions={<SegmentedTabs className="v2-alert-tabs" variant="filled" ariaLabel="告警中心分类" value={activeTab} items={tabs} onChange={setTab} />}
/>
{activeTab !== 'notifications' && rules.isError ? <InlineError message={rules.error.message} onRetry={() => rules.refetch()} /> : null}
{activeTab === 'rules' && metrics.isError ? <InlineError message={metrics.error.message} onRetry={() => metrics.refetch()} /> : null}
{activeTab === 'events'
? <EventWorkspace filters={filters} draft={eventDraft} setDraft={setEventDraft} setFilters={setFilters} rules={rules.data ?? []} unread={unread} editable={operator} onTab={setTab} />
: activeTab === 'rules'
? <RulesWorkspace rules={rules.data ?? []} metrics={metrics.data?.metrics ?? []} />
: <NotificationsWorkspace editable={operator} />}
</div>;
} }

View File

@@ -165,7 +165,8 @@ describe('V2 production entry', () => {
expect(corePageSources.AlertsPage).toContain('<Card className="v2-alert-kpis-card v2-alert-context-card"'); expect(corePageSources.AlertsPage).toContain('<Card className="v2-alert-kpis-card v2-alert-context-card"');
expect(corePageSources.AlertsPage).toContain('<Card className="v2-alert-table-card"'); expect(corePageSources.AlertsPage).toContain('<Card className="v2-alert-table-card"');
expect(corePageSources.AlertsPage).toContain('<Card className={`v2-alert-inspector'); expect(corePageSources.AlertsPage).toContain('<Card className={`v2-alert-inspector');
expect(corePageSources.AlertsPage).toContain('className="v2-alert-navigation"'); expect(corePageSources.AlertsPage).toContain('<WorkspaceCommandBar');
expect(corePageSources.AlertsPage).toContain('className="v2-alert-navigation v2-alert-command-bar"');
expect(corePageSources.AlertsPage).toContain('<SideSheet\n className="v2-alert-filter-sidesheet"'); expect(corePageSources.AlertsPage).toContain('<SideSheet\n className="v2-alert-filter-sidesheet"');
expect(corePageSources.AlertsPage).toContain('<SideSheet\n className="v2-alert-detail-sidesheet"'); expect(corePageSources.AlertsPage).toContain('<SideSheet\n className="v2-alert-detail-sidesheet"');
expect(corePageSources.AlertsPage).toContain('className={`v2-alert-event-table'); expect(corePageSources.AlertsPage).toContain('className={`v2-alert-event-table');

View File

@@ -6649,6 +6649,35 @@
box-shadow: 0 5px 18px rgba(31, 53, 80, .045); box-shadow: 0 5px 18px rgba(31, 53, 80, .045);
} }
.v2-alert-command-bar.v2-workspace-command-bar {
max-width: none;
padding: 5px 7px 5px 14px;
}
.v2-alert-command-bar .v2-workspace-command-copy {
max-width: 310px;
flex: 1 1 220px;
}
.v2-alert-command-bar .v2-workspace-command-copy > .semi-typography:first-child {
font-size: 14px;
}
.v2-alert-command-bar .v2-workspace-command-copy > .semi-typography:last-child {
max-width: 310px;
font-size: 10px;
}
.v2-alert-command-bar .v2-workspace-command-actions {
flex: 1 1 auto;
justify-content: flex-end;
gap: 9px;
}
.v2-alert-command-bar .v2-workspace-command-actions > .v2-alert-tabs {
order: -1;
}
.v2-alert-navigation .v2-alert-tabs.v2-segmented-tabs { .v2-alert-navigation .v2-alert-tabs.v2-segmented-tabs {
width: auto; width: auto;
min-height: 40px; min-height: 40px;
@@ -7349,6 +7378,22 @@
padding: 4px; padding: 4px;
} }
.v2-alert-command-bar.v2-workspace-command-bar {
display: block;
min-height: 50px;
}
.v2-alert-command-bar .v2-workspace-command-copy,
.v2-alert-command-bar .v2-workspace-command-actions > .semi-tag,
.v2-alert-command-bar .v2-workspace-command-meta {
display: none;
}
.v2-alert-command-bar .v2-workspace-command-actions {
display: block;
width: 100%;
}
.v2-alert-navigation .v2-alert-tabs.v2-segmented-tabs { .v2-alert-navigation .v2-alert-tabs.v2-segmented-tabs {
position: static; position: static;
width: 100%; width: 100%;