polish Semi UI alert subworkspaces

This commit is contained in:
lingniu
2026-07-18 18:56:01 +08:00
parent db1079ae27
commit 84684f2dc1
3 changed files with 282 additions and 30 deletions

View File

@@ -86,7 +86,8 @@ test('loads a paginated notification page and an independent unread total on dir
expect(view.container.querySelector('.v2-alert-notification-empty.semi-empty')).toBeInTheDocument(); expect(view.container.querySelector('.v2-alert-notification-empty.semi-empty')).toBeInTheDocument();
expect(view.container.querySelector('.v2-alert-notification-pagination')).toBeInTheDocument(); expect(view.container.querySelector('.v2-alert-notification-pagination')).toBeInTheDocument();
expect(screen.getByRole('combobox', { name: '每页通知数' })).toBeInTheDocument(); expect(screen.getByRole('combobox', { name: '每页通知数' })).toBeInTheDocument();
expect(view.container.querySelector('.v2-alert-channel-card.semi-card')).toBeInTheDocument(); expect(view.container.querySelector('.v2-alert-channel-collapse.semi-collapse')).toBeInTheDocument();
expect(screen.getByText('3 个 · 未启用')).toBeInTheDocument();
expect(view.container.querySelector('.v2-alert-channel-descriptions.semi-descriptions')).toBeInTheDocument(); expect(view.container.querySelector('.v2-alert-channel-descriptions.semi-descriptions')).toBeInTheDocument();
expect(mocks.alertRulesV2).not.toHaveBeenCalled(); expect(mocks.alertRulesV2).not.toHaveBeenCalled();
expect(mocks.metricCatalog).not.toHaveBeenCalled(); expect(mocks.metricCatalog).not.toHaveBeenCalled();
@@ -112,6 +113,18 @@ test('ends notification mutation feedback with a visible retryable error instead
expect(screen.getByRole('button', { name: '标为已读' })).toBeEnabled(); expect(screen.getByRole('button', { name: '标为已读' })).toBeEnabled();
}); });
test('keeps the mobile notification title, count, and compact bulk action visible together', async () => {
layout.mobile = true;
mocks.alertNotificationsV2.mockResolvedValue({ items: [{ id: 8, eventId: 'event-8', title: '车辆告警', content: '移动端告警', severity: 'major', read: false, createdAt: '2026-07-16T04:00:00Z' }], total: 1, limit: 100, offset: 0 });
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
render(<QueryClientProvider client={client}><MemoryRouter future={ROUTER_FUTURE} initialEntries={['/alerts?tab=notifications']}><AlertsPage /></MemoryRouter></QueryClientProvider>);
const heading = await screen.findByRole('heading', { level: 5, name: /通知列表/ });
await waitFor(() => expect(heading).toHaveTextContent('1 条'));
expect(heading.querySelector('.v2-alert-notification-total.semi-tag')).toBeInTheDocument();
expect(screen.getByRole('button', { name: '本页已读' })).toBeInTheDocument();
});
test('clears old alert rows and inspector evidence when the event scope changes', async () => { test('clears old alert rows and inspector evidence when the event scope changes', async () => {
const oldEvent = alertEvent('old-event', 'OLDVIN', '旧告警车牌'); const oldEvent = alertEvent('old-event', 'OLDVIN', '旧告警车牌');
oldEvent.actions = [{ id: 1, action: 'detect', fromStatus: '', toStatus: 'unprocessed', actor: 'alert-evaluator', note: '规则首次命中', createdAt: '2026-07-16T04:00:00Z' }]; oldEvent.actions = [{ id: 1, action: 'detect', fromStatus: '', toStatus: 'unprocessed', actor: 'alert-evaluator', note: '规则首次命中', createdAt: '2026-07-16T04:00:00Z' }];
@@ -324,6 +337,7 @@ test('keeps mobile rule selection focused and opens editing in a Semi bottom Sid
expect(document.querySelector('.v2-alert-rule-editor-sidesheet .semi-sidesheet-inner')).toHaveStyle({ height: 'min(92dvh, 820px)' }); expect(document.querySelector('.v2-alert-rule-editor-sidesheet .semi-sidesheet-inner')).toHaveStyle({ height: 'min(92dvh, 820px)' });
expect(within(editor).getByDisplayValue('测试超速规则')).toBeInTheDocument(); expect(within(editor).getByDisplayValue('测试超速规则')).toBeInTheDocument();
expect(within(editor).getByRole('button', { name: '保存规则' })).toBeInTheDocument(); expect(within(editor).getByRole('button', { name: '保存规则' })).toBeInTheDocument();
expect(within(editor).queryByRole('region', { name: '告警规则模板' })).not.toBeInTheDocument();
expect(ruleItem).toHaveAttribute('aria-expanded', 'true'); expect(ruleItem).toHaveAttribute('aria-expanded', 'true');
fireEvent.click(within(editor).getByRole('button', { name: '关闭告警规则编辑' })); fireEvent.click(within(editor).getByRole('button', { name: '关闭告警规则编辑' }));
@@ -337,6 +351,7 @@ test('keeps mobile rule selection focused and opens editing in a Semi bottom Sid
await waitFor(() => expect(document.querySelector('.v2-alert-rule-editor')).toBeInTheDocument()); await waitFor(() => expect(document.querySelector('.v2-alert-rule-editor')).toBeInTheDocument());
const newEditor = screen.getByRole('dialog', { name: '告警规则编辑' }); const newEditor = screen.getByRole('dialog', { name: '告警规则编辑' });
expect(within(newEditor).getByText('新建规则')).toBeInTheDocument(); expect(within(newEditor).getByText('新建规则')).toBeInTheDocument();
expect(within(newEditor).getByRole('region', { name: '告警规则模板' })).toBeInTheDocument();
expect(newRule).toHaveAttribute('aria-expanded', 'true'); expect(newRule).toHaveAttribute('aria-expanded', 'true');
}); });
@@ -363,7 +378,9 @@ test('creates auditable drafts from simple offline and hydrogen rule templates',
await waitFor(() => expect(ruleItem).toHaveAttribute('aria-pressed', 'true')); await waitFor(() => expect(ruleItem).toHaveAttribute('aria-pressed', 'true'));
expect(within(ruleItem).getByText('重要').closest('.semi-tag')).toBeTruthy(); expect(within(ruleItem).getByText('重要').closest('.semi-tag')).toBeTruthy();
expect(within(ruleItem).getByText('已启用').closest('.semi-tag')).toBeTruthy(); expect(within(ruleItem).getByText('已启用').closest('.semi-tag')).toBeTruthy();
expect(screen.queryByRole('region', { name: '告警规则模板' })).not.toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: /新建规则/ }));
const offlineTemplate = await screen.findByRole('button', { name: /离线超过 10 小时/ }); const offlineTemplate = await screen.findByRole('button', { name: /离线超过 10 小时/ });
expect(offlineTemplate).toHaveClass('semi-button', 'v2-alert-template-card'); expect(offlineTemplate).toHaveClass('semi-button', 'v2-alert-template-card');
expect(within(offlineTemplate).getByText('GB32960 / JT808 / YUTONG_MQTT').closest('.semi-tag')).toBeTruthy(); expect(within(offlineTemplate).getByText('GB32960 / JT808 / YUTONG_MQTT').closest('.semi-tag')).toBeTruthy();

View File

@@ -368,7 +368,7 @@ function RulesWorkspace({ rules, metrics }: { rules: AlertRule[]; metrics: Metri
</span> </span>
{toggleButton} {toggleButton}
</div>} </div>}
<section className="v2-alert-rule-templates" aria-label="告警规则模板"> {!draft.version ? <section className="v2-alert-rule-templates" aria-label="告警规则模板">
<div><strong></strong><span></span></div> <div><strong></strong><span></span></div>
<nav>{RULE_TEMPLATES.map((template) => { <nav>{RULE_TEMPLATES.map((template) => {
const available = metrics.some((metric) => metric.key === template.draft.metric && metric.alertable); const available = metrics.some((metric) => metric.key === template.draft.metric && metric.alertable);
@@ -385,7 +385,7 @@ function RulesWorkspace({ rules, metrics }: { rules: AlertRule[]; metrics: Metri
<Tag size="small" color={available ? 'blue' : 'grey'} type="light">{available ? (template.draft.scopeProtocols.join(' / ') || '全部协议') : '不可用'}</Tag> <Tag size="small" color={available ? 'blue' : 'grey'} type="light">{available ? (template.draft.scopeProtocols.join(' / ') || '全部协议') : '不可用'}</Tag>
</Button>; </Button>;
})}</nav> })}</nav>
</section> </section> : null}
<div className="v2-rule-form-grid"> <div className="v2-rule-form-grid">
<label><span></span><Input required maxLength={80} value={draft.name} onChange={(value) => setDraft({ ...draft, name: value })} /></label> <label><span></span><Input required maxLength={80} value={draft.name} onChange={(value) => setDraft({ ...draft, name: value })} /></label>
<label><span></span><Select value={draft.severity} onChange={(value) => setDraft({ ...draft, severity: String(value) as AlertRuleInput['severity'] })} optionList={[{ value: 'critical', label: '紧急' }, { value: 'major', label: '重要' }, { value: 'minor', label: '一般' }]} /></label> <label><span></span><Select value={draft.severity} onChange={(value) => setDraft({ ...draft, severity: String(value) as AlertRuleInput['severity'] })} optionList={[{ value: 'critical', label: '紧急' }, { value: 'major', label: '重要' }, { value: 'minor', label: '一般' }]} /></label>
@@ -434,7 +434,7 @@ function RulesWorkspace({ rules, metrics }: { rules: AlertRule[]; metrics: Metri
</span> </span>
<Tag className="v2-alert-rule-state" size="small" color={rule.enabled ? 'green' : 'grey'} type="light">{rule.enabled ? '已启用' : '已停用'}</Tag> <Tag className="v2-alert-rule-state" size="small" color={rule.enabled ? 'green' : 'grey'} type="light">{rule.enabled ? '已启用' : '已停用'}</Tag>
</Button>)} </Button>)}
{!rules.length ? <Empty className="v2-alert-rule-empty" title="暂无告警规则" description="从右侧模板快速创建,或新建一条自定义规则。" /> : null} {!rules.length ? <Empty className="v2-alert-rule-empty" title="暂无告警规则" description="新建规则后可从常用模板开始,也可直接配置自定义条件。" /> : null}
</div> </div>
</Card> </Card>
{!mobileLayout ? editor : null} {!mobileLayout ? editor : null}
@@ -454,6 +454,7 @@ function RulesWorkspace({ rules, metrics }: { rules: AlertRule[]; metrics: Metri
function NotificationsWorkspace({ editable }: { editable: boolean }) { function NotificationsWorkspace({ editable }: { editable: boolean }) {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const mobileLayout = useMobileLayout();
const [offset, setOffset] = useState(0); const [offset, setOffset] = useState(0);
const [limit, setLimit] = useState(20); const [limit, setLimit] = useState(20);
const notifications = useQuery({ const notifications = useQuery({
@@ -470,17 +471,22 @@ function NotificationsWorkspace({ editable }: { editable: boolean }) {
useEffect(() => { useEffect(() => {
if (offset > 0 && offset >= total && !notifications.isPending) setOffset(Math.max(0, (totalPages - 1) * limit)); if (offset > 0 && offset >= total && !notifications.isPending) setOffset(Math.max(0, (totalPages - 1) * limit));
}, [limit, notifications.isPending, offset, total, totalPages]); }, [limit, notifications.isPending, offset, total, totalPages]);
return <Card className="v2-alert-notifications" bodyStyle={{ padding: 0 }}><WorkspacePanelHeader title="站内通知" description="仅站内通道具备真实送达与已读状态" meta={`${total.toLocaleString('zh-CN')}`} actions={editable ? <Button theme="light" disabled={read.isPending || !items.some((item) => !item.read)} onClick={() => read.mutate(items.filter((item) => !item.read).map((item) => item.id))}>{read.isPending ? '正在更新' : '本页全部已读'}</Button> : <span className="v2-role-badge"></span>} />{notifications.isError ? <InlineError message={notifications.error?.message ?? '站内通知读取失败'} onRetry={() => notifications.refetch()} /> : null}{read.isError ? <InlineError message={read.error instanceof Error ? read.error.message : '通知状态更新失败'} /> : null} const totalTag = <Tag className="v2-alert-notification-total" color="blue" type="light" size="small">{total.toLocaleString('zh-CN')} </Tag>;
return <Card className="v2-alert-notifications" bodyStyle={{ padding: 0 }}><WorkspacePanelHeader className="v2-alert-notification-heading" title={mobileLayout ? <span className="v2-alert-notification-mobile-title">{totalTag}</span> : '站内通知'} description="仅站内通道具备真实送达与已读状态" meta={mobileLayout ? undefined : totalTag} actions={editable ? <Button theme="light" type="primary" disabled={read.isPending || !items.some((item) => !item.read)} onClick={() => read.mutate(items.filter((item) => !item.read).map((item) => item.id))}>{read.isPending ? '正在更新' : mobileLayout ? '本页已读' : '本页全部已读'}</Button> : <span className="v2-role-badge"></span>} />{notifications.isError ? <InlineError message={notifications.error?.message ?? '站内通知读取失败'} onRetry={() => notifications.refetch()} /> : null}{read.isError ? <InlineError message={read.error instanceof Error ? read.error.message : '通知状态更新失败'} /> : null}
<div className="v2-alert-notification-list">{notifications.isPending ? <div className="v2-alert-notification-loading"><Spin size="middle" tip="正在读取站内通知" /></div> : items.length ? <CardGroup className="v2-alert-notification-cards" type="grid" spacing={0}>{items.map((item) => <Card className={`v2-alert-notification-card${item.read ? ' is-read' : ' is-unread'}`} key={item.id} title={<span className="v2-alert-notification-title"><SeverityTag severity={item.severity} /><span title={item.title}>{item.title}</span></span>} headerExtraContent={<Tag color={item.read ? 'grey' : 'orange'} type="light" size="small">{item.read ? '已读' : '未读'}</Tag>} headerLine bodyStyle={{ padding: 0 }}> <div className="v2-alert-notification-list">{notifications.isPending ? <div className="v2-alert-notification-loading"><Spin size="middle" tip="正在读取站内通知" /></div> : items.length ? <CardGroup className="v2-alert-notification-cards" type="grid" spacing={0}>{items.map((item) => <Card className={`v2-alert-notification-card${item.read ? ' is-read' : ' is-unread'}`} key={item.id} title={<span className="v2-alert-notification-title"><SeverityTag severity={item.severity} /><span title={item.title}>{item.title}</span></span>} headerExtraContent={<Tag color={item.read ? 'grey' : 'orange'} type="light" size="small">{item.read ? '已读' : '未读'}</Tag>} headerLine bodyStyle={{ padding: 0 }}>
<p className="v2-alert-notification-content" title={item.content}>{item.content}</p> <p className="v2-alert-notification-content" title={item.content}>{item.content}</p>
<footer><Typography.Text type="tertiary"><AlertTime value={item.createdAt} /></Typography.Text>{editable && !item.read ? <Button theme="borderless" disabled={read.isPending} onClick={() => read.mutate([item.id])}>{read.isPending ? '更新中' : '标为已读'}</Button> : null}</footer> <footer><Typography.Text type="tertiary"><AlertTime value={item.createdAt} /></Typography.Text>{editable && !item.read ? <Button theme="borderless" disabled={read.isPending} onClick={() => read.mutate([item.id])}>{read.isPending ? '更新中' : '标为已读'}</Button> : null}</footer>
</Card>)}</CardGroup> : !notifications.isError ? <Empty className="v2-alert-notification-empty" image={<IconBell />} title="暂无站内通知" description="告警触发或状态变更后,通知会在这里形成可追溯记录。" /> : null}</div> </Card>)}</CardGroup> : !notifications.isError ? <Empty className="v2-alert-notification-empty" image={<IconBell />} title="暂无站内通知" description="告警触发或状态变更后,通知会在这里形成可追溯记录。" /> : null}</div>
<footer className="v2-alert-notification-pagination"><TablePagination page={page} totalPages={totalPages} info={`${total.toLocaleString('zh-CN')} 条 · 本页 ${items.length.toLocaleString('zh-CN')}`} disabled={notifications.isFetching} onPageChange={(next) => setOffset((next - 1) * limit)} pageSize={limit} pageSizeLabel="每页通知数" onPageSizeChange={(next) => { setLimit(next); setOffset(0); }} pageSizeOptions={[{ value: 20, label: '20 条/页' }, { value: 50, label: '50 条/页' }]} /></footer> <footer className="v2-alert-notification-pagination"><TablePagination page={page} totalPages={totalPages} info={`${total.toLocaleString('zh-CN')} 条 · 本页 ${items.length.toLocaleString('zh-CN')}`} disabled={notifications.isFetching} onPageChange={(next) => setOffset((next - 1) * limit)} pageSize={limit} pageSizeLabel="每页通知数" onPageSizeChange={(next) => { setLimit(next); setOffset(0); }} pageSizeOptions={[{ value: 20, label: '20 条/页' }, { value: 50, label: '50 条/页' }]} /></footer>
<Card className="v2-alert-channel-card" title={<strong></strong>} headerLine bodyStyle={{ padding: 0 }}><Descriptions className="v2-alert-channel-descriptions" align="left" size="small" data={[ <Collapse className="v2-alert-channel-collapse" keepDOM>
{ key: '短信SMS', value: <Tag color="grey" type="light" size="small"> · </Tag> }, <Collapse.Panel itemKey="external-channels" header={<span className="v2-alert-channel-heading"><span><strong></strong><small></small></span><Tag color="grey" type="light" size="small">3 · </Tag></span>}>
{ key: '邮件Email', value: <Tag color="grey" type="light" size="small"> · </Tag> }, <Descriptions className="v2-alert-channel-descriptions" align="left" size="small" data={[
{ key: '企业微信WeCom', value: <Tag color="grey" type="light" size="small"> · </Tag> } { key: '短信SMS', value: <Tag color="grey" type="light" size="small"> · </Tag> },
]} /></Card> { key: '邮件Email', value: <Tag color="grey" type="light" size="small"> · </Tag> },
{ key: '企业微信WeCom', value: <Tag color="grey" type="light" size="small"> · </Tag> }
]} />
</Collapse.Panel>
</Collapse>
</Card>; </Card>;
} }

View File

@@ -7940,17 +7940,56 @@
.v2-alert-notification-list { .v2-alert-notification-list {
min-height: 0; min-height: 0;
overflow: auto; overflow: auto;
padding: 12px; padding: 10px;
scrollbar-color: #aebdce transparent;
scrollbar-width: thin;
}
.v2-alert-notification-list::-webkit-scrollbar {
width: 10px;
}
.v2-alert-notification-list::-webkit-scrollbar-thumb {
border: 2px solid transparent;
border-radius: 999px;
background: #aebdce;
background-clip: padding-box;
} }
.v2-alert-notification-cards.semi-card-group { .v2-alert-notification-cards.semi-card-group {
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 11px; gap: 8px;
} }
.v2-alert-notification-card.semi-card { .v2-alert-notification-card.semi-card {
content-visibility: auto; content-visibility: auto;
contain-intrinsic-size: auto 132px; contain-intrinsic-size: auto 116px;
}
.v2-alert-notification-card > .semi-card-header {
min-height: 44px;
padding-inline: 11px;
}
.v2-alert-notification-card > .semi-card-body {
min-height: 72px;
gap: 0;
}
.v2-alert-notification-content {
min-height: 42px;
padding: 8px 11px 5px;
line-height: 1.5;
}
.v2-alert-notification-card > .semi-card-body > footer {
min-height: 30px;
padding: 3px 7px 3px 11px;
}
.v2-alert-notification-card footer .semi-button {
height: 24px;
padding-inline: 7px;
} }
.v2-alert-notification-pagination { .v2-alert-notification-pagination {
@@ -7964,15 +8003,77 @@
padding: 6px 12px; padding: 6px 12px;
} }
.v2-alert-channel-card.semi-card { .v2-alert-notification-total.semi-tag {
border-width: 1px 0 0; min-height: 24px;
border-radius: 0; border-radius: 999px;
box-shadow: none; padding-inline: 9px;
font-variant-numeric: tabular-nums;
} }
.v2-alert-channel-card > .semi-card-header { .v2-alert-channel-collapse.semi-collapse {
min-height: 38px; overflow: hidden;
padding: 0 14px; border: 0;
border-top: 1px solid #e4eaf1;
border-radius: 0;
background: #fff;
}
.v2-alert-channel-collapse > .semi-collapse-item {
margin: 0;
border: 0;
}
.v2-alert-channel-collapse .semi-collapse-header {
min-height: 42px;
padding: 5px 14px;
}
.v2-alert-channel-collapse .semi-collapse-header:hover {
background: #f7faff;
}
.v2-alert-channel-collapse .semi-collapse-content {
border-top: 1px solid #edf1f5;
background: #fff;
}
.v2-alert-channel-collapse .semi-collapse-content-wrapper {
padding: 0;
}
.v2-alert-channel-heading {
display: flex;
width: 100%;
min-width: 0;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.v2-alert-channel-heading > span {
display: grid;
min-width: 0;
gap: 1px;
}
.v2-alert-channel-heading strong {
color: #4c5e74;
font-size: 11px;
}
.v2-alert-channel-heading small {
overflow: hidden;
color: #8995a5;
font-size: 9px;
font-weight: 400;
text-overflow: ellipsis;
white-space: nowrap;
}
.v2-alert-channel-heading > .semi-tag {
flex: 0 0 auto;
border-radius: 999px;
font-size: 9px;
} }
.v2-alert-channel-descriptions.semi-descriptions { .v2-alert-channel-descriptions.semi-descriptions {
@@ -8484,30 +8585,139 @@
justify-content: center; justify-content: center;
} }
.v2-alert-page.is-notifications {
height: 100%;
min-height: 0;
overflow: hidden;
padding-bottom: 8px;
}
.v2-alert-notifications.semi-card { .v2-alert-notifications.semi-card {
min-height: 540px; min-height: 0;
flex: none; flex: 1 1 0;
} }
.v2-alert-notifications > .semi-card-body { .v2-alert-notifications > .semi-card-body {
grid-template-rows: 58px minmax(320px, 1fr) 76px auto; grid-template-rows: 52px minmax(0, 1fr) 58px auto;
}
.v2-alert-notifications > .semi-card-body > .v2-alert-notification-heading {
min-height: 52px;
padding: 6px 8px 6px 10px;
}
.v2-alert-notification-heading .v2-workspace-panel-copy {
flex: 1 1 auto;
gap: 0;
}
.v2-alert-notification-heading .v2-workspace-panel-copy > h5.semi-typography {
font-size: 14px;
}
.v2-alert-notification-heading .v2-workspace-panel-copy > .semi-typography:not(h5) {
display: none;
}
.v2-alert-notification-heading .v2-workspace-panel-actions {
flex: 0 0 auto;
gap: 5px;
}
.v2-alert-notification-heading .v2-workspace-panel-actions > .semi-button {
min-height: 32px;
border-radius: 8px;
padding-inline: 8px;
font-size: 10px;
}
.v2-alert-notification-total.semi-tag {
min-height: 22px;
padding-inline: 7px;
font-size: 9px;
}
.v2-alert-notification-mobile-title {
display: flex;
min-width: 0;
align-items: center;
gap: 6px;
}
.v2-alert-notification-mobile-title > .v2-alert-notification-total.semi-tag {
flex: 0 0 auto;
}
.v2-alert-notification-list {
padding: 6px;
} }
.v2-alert-notification-cards.semi-card-group { .v2-alert-notification-cards.semi-card-group {
grid-template-columns: 1fr; grid-template-columns: 1fr;
gap: 6px;
}
.v2-alert-notification-card.semi-card {
border-radius: 9px;
contain-intrinsic-size: auto 102px;
}
.v2-alert-notification-card > .semi-card-header {
min-height: 40px;
padding-inline: 9px;
}
.v2-alert-notification-title {
gap: 5px;
}
.v2-alert-notification-title .v2-alert-severity.semi-tag,
.v2-alert-notification-card > .semi-card-header .semi-card-header-wrapper-extra > .semi-tag {
min-height: 20px;
}
.v2-alert-notification-title > span:last-child {
font-size: 11px;
}
.v2-alert-notification-card > .semi-card-body {
min-height: 62px;
}
.v2-alert-notification-content {
min-height: 34px;
padding: 6px 9px 3px;
font-size: 10px;
line-height: 1.45;
-webkit-line-clamp: 1;
}
.v2-alert-notification-card > .semi-card-body > footer {
min-height: 28px;
padding: 2px 5px 2px 9px;
}
.v2-alert-notification-card footer .semi-typography,
.v2-alert-notification-card footer .semi-button {
font-size: 9px;
}
.v2-alert-notification-card footer .semi-button {
height: 24px;
padding-inline: 6px;
} }
.v2-alert-notification-pagination { .v2-alert-notification-pagination {
min-height: 76px; min-height: 58px;
align-items: stretch; align-items: center;
justify-content: center; justify-content: flex-end;
flex-direction: column; flex-direction: row;
gap: 7px; gap: 5px;
padding: 8px 10px; padding: 5px 6px;
} }
.v2-alert-notification-pagination .v2-table-pagination-info { .v2-alert-notification-pagination .v2-table-pagination-info {
width: 100%; display: none;
} }
.v2-alert-notification-pagination .v2-table-pagination-controls { .v2-alert-notification-pagination .v2-table-pagination-controls {
@@ -8518,6 +8728,25 @@
flex: 1 1 auto; flex: 1 1 auto;
} }
.v2-alert-notification-pagination .v2-table-pagination-button.semi-button,
.v2-alert-notification-pagination .v2-table-pagination-current,
.v2-alert-notification-pagination .v2-table-pagination-size.semi-select {
height: 34px;
}
.v2-alert-channel-collapse .semi-collapse-header {
min-height: 40px;
padding: 4px 8px;
}
.v2-alert-channel-heading small {
max-width: 190px;
}
.v2-alert-channel-heading > .semi-tag {
font-size: 8px;
}
.v2-alert-channel-descriptions tbody { .v2-alert-channel-descriptions tbody {
display: table-row-group; display: table-row-group;
} }