unify Semi UI protocol evidence
This commit is contained in:
@@ -159,6 +159,7 @@ test('clears old alert rows and inspector evidence when the event scope changes'
|
||||
expect(view.container.querySelector('.v2-alert-event-table.semi-table-wrapper')).not.toHaveClass('is-compact');
|
||||
expect(screen.getByRole('columnheader', { name: '触发 / 阈值' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('columnheader', { name: '位置' })).toBeInTheDocument();
|
||||
expect(view.container.querySelector('.v2-alert-event-table .v2-alert-protocol-tag.semi-tag')).toHaveTextContent('JT/T 808');
|
||||
expect(view.container.querySelector('.v2-alert-table-scroll > table')).not.toBeInTheDocument();
|
||||
expect(view.container.querySelector('.v2-alert-mobile-list')).not.toBeInTheDocument();
|
||||
expect(view.container.querySelector('time[datetime="2026-07-16T04:00:00Z"]')).toHaveTextContent('07-16 12:00:00');
|
||||
@@ -176,7 +177,7 @@ test('clears old alert rows and inspector evidence when the event scope changes'
|
||||
expect(screen.getByText('已展开处置详情 · 点击其他事件快速切换')).toBeInTheDocument();
|
||||
expect(desktopAlertRow).toHaveAttribute('aria-expanded', 'true');
|
||||
expect(view.container.querySelector('.v2-alert-focus-card[aria-label="告警处置摘要"]')).toHaveClass('v2-alert-detail-card');
|
||||
expect(screen.getByLabelText('告警事件上下文')).toHaveTextContent('数据来源JT808触发时间07-16 12:00:00处理记录1 条');
|
||||
expect(screen.getByLabelText('告警事件上下文')).toHaveTextContent('数据来源JT/T 808触发时间07-16 12:00:00处理记录1 条');
|
||||
expect(screen.getByLabelText('告警触发证据')).toHaveTextContent('触发值90 km/h阈值条件> 80 km/h,持续 60 秒超限幅度+10 km/h');
|
||||
expect(screen.getByText('1 条记录').closest('.semi-tag')).toBeInTheDocument();
|
||||
expect(screen.getByText('可操作').closest('.semi-tag')).toBeInTheDocument();
|
||||
@@ -255,6 +256,7 @@ test('renders only selectable Semi alert cards on mobile', async () => {
|
||||
expect(view.container.querySelector('.v2-alert-event-table')).not.toBeInTheDocument();
|
||||
expect(action).toHaveAttribute('aria-expanded', 'false');
|
||||
expect(action).toHaveTextContent('超限幅度+10 km/h');
|
||||
expect(action.querySelector('.v2-alert-protocol-tag.semi-tag')).toHaveTextContent('JT/T 808');
|
||||
expect(action).toHaveTextContent('核验并处置');
|
||||
fireEvent.click(action);
|
||||
expect(action).toHaveAttribute('aria-pressed', 'true');
|
||||
|
||||
@@ -8,6 +8,7 @@ import type { AlertEvent, AlertQuery, AlertRule, AlertRuleInput, AlertStatus, Me
|
||||
import { actionLabels, alertDeltaText, alertValue, canAct, formatAlertTime, operatorLabels, ruleCondition, severityLabels, statusLabels, thresholdText } from '../domain/alert';
|
||||
import { InlineError, PanelEmpty, PanelLoading } from '../shared/AsyncState';
|
||||
import { MetricActionButton } from '../shared/MetricActionButton';
|
||||
import { ProtocolTag } from '../shared/ProtocolTag';
|
||||
import { SegmentedTabs } from '../shared/SegmentedTabs';
|
||||
import { TablePagination } from '../shared/TablePagination';
|
||||
import { WorkspaceCommandBar } from '../shared/WorkspaceCommandBar';
|
||||
@@ -83,7 +84,7 @@ const AlertEventTable = memo(function AlertEventTable({ rows, selectedID, compac
|
||||
render: (_: string, event: AlertEvent) => <div className="v2-alert-event-vehicle"><strong>{event.plate || '未绑定车牌'}</strong><small>{event.vin}</small></div>
|
||||
},
|
||||
{ title: '规则', dataIndex: 'ruleName', width: 170, render: (value: string) => <span className="v2-alert-event-rule" title={value}>{value}</span> },
|
||||
{ title: '协议', dataIndex: 'protocol', width: 92, render: (value: string) => value || '—' },
|
||||
{ title: '协议', dataIndex: 'protocol', width: 112, render: (value: string) => <ProtocolTag className="v2-alert-protocol-tag" protocol={value} compact /> },
|
||||
{ title: '触发时间', dataIndex: 'triggeredAt', width: 132, render: (value: string) => <AlertTime value={value} /> },
|
||||
{ title: '状态', dataIndex: 'status', width: 90, render: (_: AlertEvent['status'], event: AlertEvent) => <StatusTag status={event.status} /> },
|
||||
{
|
||||
@@ -116,7 +117,7 @@ function EventInspector({ event, note, acting, actionError, editable, onNote, on
|
||||
if (!event) return <Card className="v2-alert-inspector" bodyStyle={{ padding: 0 }}><Empty className="v2-alert-inspector-empty" image={<IconAlarm />} title="选择告警事件" description="查看触发证据、状态时间线和处置动作。" /></Card>;
|
||||
const actionCount = event.actions?.length ?? 0;
|
||||
return <Card className={`v2-alert-inspector${sheet ? ' is-sheet' : ''}`} bodyStyle={{ padding: 0 }}>
|
||||
{!sheet ? <WorkspacePanelHeader className="v2-alert-inspector-heading" title="事件处置" description={event.ruleName} actions={<><span className="v2-alert-inspector-status"><SeverityTag severity={event.severity} /><StatusTag status={event.status} /></span><Button className="v2-alert-inspector-close" theme="borderless" icon={<IconClose />} aria-label="关闭告警详情" onClick={onClose} /></>} /> : null}
|
||||
{!sheet ? <WorkspacePanelHeader className="v2-alert-inspector-heading" title="事件处置" description={event.ruleName} actions={<><span className="v2-alert-inspector-status"><SeverityTag severity={event.severity} /></span><Button className="v2-alert-inspector-close" theme="borderless" icon={<IconClose />} aria-label="关闭告警详情" onClick={onClose} /></>} /> : null}
|
||||
<div className="v2-alert-inspector-content">
|
||||
<Card className="v2-alert-detail-card v2-alert-focus-card" bodyStyle={{ padding: 0 }} aria-label="告警处置摘要">
|
||||
<header className="v2-alert-focus-identity">
|
||||
@@ -124,7 +125,7 @@ function EventInspector({ event, note, acting, actionError, editable, onNote, on
|
||||
<span className="v2-alert-focus-current"><small>当前状态</small><StatusTag status={event.status} /></span>
|
||||
</header>
|
||||
<div className="v2-alert-focus-facts" aria-label="告警事件上下文">
|
||||
<span><small>数据来源</small><strong><Tag color="blue" type="light" size="small">{event.protocol || '未知协议'}</Tag></strong></span>
|
||||
<span><small>数据来源</small><strong><ProtocolTag className="v2-alert-protocol-tag" protocol={event.protocol} compact unknownLabel="未知协议" /></strong></span>
|
||||
<span><small>触发时间</small><strong><AlertTime value={event.triggeredAt} /></strong></span>
|
||||
<span><small>处理记录</small><strong>{actionCount} 条</strong></span>
|
||||
</div>
|
||||
@@ -263,7 +264,7 @@ function EventWorkspace({ filters, draft, setDraft, setFilters, rules, unread, e
|
||||
aria-label={mobileLayout ? '告警事件列表,可上下滚动' : undefined}
|
||||
>
|
||||
{mobileLayout
|
||||
? <div className="v2-alert-mobile-list">{rows.map((event) => <Card key={event.id} className={`v2-alert-mobile-card${selectedID === event.id ? ' is-selected' : ''}`} bodyStyle={{ padding: 0 }}><Button theme="borderless" type="tertiary" className="v2-alert-mobile-action" aria-pressed={selectedID === event.id} aria-expanded={selectedID === event.id} aria-label={`查看 ${event.plate || event.vin} ${event.ruleName} 告警详情`} onClick={() => selectEvent(event.id)}><span className="v2-alert-mobile-card-content"><header><strong>{event.plate || '未绑定车牌'}</strong><span><SeverityTag severity={event.severity} /><StatusTag status={event.status} /></span></header><p>{event.ruleName}</p><dl><div><dt>触发时间</dt><dd><AlertTime value={event.triggeredAt} /></dd></div><div><dt>数据来源</dt><dd>{event.protocol || '—'}</dd></div><div><dt>超限幅度</dt><dd>{alertDeltaText(event)}</dd></div></dl><footer>核验并处置<IconChevronRight /></footer></span></Button></Card>)}</div>
|
||||
? <div className="v2-alert-mobile-list">{rows.map((event) => <Card key={event.id} className={`v2-alert-mobile-card${selectedID === event.id ? ' is-selected' : ''}`} bodyStyle={{ padding: 0 }}><Button theme="borderless" type="tertiary" className="v2-alert-mobile-action" aria-pressed={selectedID === event.id} aria-expanded={selectedID === event.id} aria-label={`查看 ${event.plate || event.vin} ${event.ruleName} 告警详情`} onClick={() => selectEvent(event.id)}><span className="v2-alert-mobile-card-content"><header><strong>{event.plate || '未绑定车牌'}</strong><span><SeverityTag severity={event.severity} /><StatusTag status={event.status} /></span></header><p>{event.ruleName}</p><dl><div><dt>触发时间</dt><dd><AlertTime value={event.triggeredAt} /></dd></div><div><dt>数据来源</dt><dd><ProtocolTag className="v2-alert-protocol-tag" protocol={event.protocol} compact /></dd></div><div><dt>超限幅度</dt><dd>{alertDeltaText(event)}</dd></div></dl><footer>核验并处置<IconChevronRight /></footer></span></Button></Card>)}</div>
|
||||
: <AlertEventTable rows={rows} selectedID={selectedID} compact={Boolean(selectedID)} onSelect={selectEvent} />}
|
||||
{events.isFetching ? <PanelLoading className="v2-alert-loading" title="正在更新事件…" description="告警列表返回后会自动更新。" compact={Boolean(rows.length)} /> : null}
|
||||
{!events.isFetching && !rows.length ? <PanelEmpty className="v2-alert-empty" title="当前筛选条件没有告警事件" description="调整车辆、严重程度、状态或时间范围后重试。" /> : null}
|
||||
|
||||
@@ -161,7 +161,7 @@ test('clears stale rows, charts, and evidence as soon as the history scope chang
|
||||
expect(view.container.querySelector('.v2-history-evidence-status')).toHaveTextContent('证据判读正常');
|
||||
expect(view.container.querySelector('.v2-evidence-values.semi-descriptions')).toBeInTheDocument();
|
||||
expect(view.container.querySelector('.v2-history-quality-tag.semi-tag')).toHaveTextContent('正常');
|
||||
expect(view.container.querySelector('.v2-history-protocol-tag.semi-tag')).toHaveTextContent('JT808');
|
||||
expect(view.container.querySelector('.v2-history-protocol-tag.semi-tag')).toHaveTextContent('JT/T 808');
|
||||
expect(view.container.querySelector('.v2-history-workspace')).toHaveClass('is-inspector-open');
|
||||
fireEvent.click(screen.getByRole('button', { name: '关闭数据详情' }));
|
||||
expect(desktopHistoryRow).toHaveAttribute('aria-expanded', 'false');
|
||||
@@ -210,7 +210,7 @@ test('renders only selectable Semi history cards on mobile', async () => {
|
||||
expect(action).toHaveAttribute('aria-expanded', 'false');
|
||||
expect(view.container.querySelector('.v2-history-table-scroll.is-mobile-scroll')).toHaveAttribute('aria-label', '历史明细列表,可上下滚动');
|
||||
expect(view.container.querySelector('.v2-history-table-scroll.is-mobile-scroll')).toHaveAttribute('tabindex', '0');
|
||||
expect(action.closest('.v2-history-mobile-card')?.querySelector('.v2-history-protocol-tag.semi-tag')).toHaveTextContent('JT808');
|
||||
expect(action.closest('.v2-history-mobile-card')?.querySelector('.v2-history-protocol-tag.semi-tag')).toHaveTextContent('JT/T 808');
|
||||
expect(view.container.querySelector('.v2-history-metric-scroll')).not.toBeInTheDocument();
|
||||
expect(view.container.querySelector('.v2-history-summary-rail')).toBeInTheDocument();
|
||||
expect(view.container.querySelector('.v2-history-result-actions')).toHaveClass('is-mobile-actions');
|
||||
|
||||
@@ -11,6 +11,7 @@ import { formatShanghaiDateTime } from '../domain/formatters';
|
||||
import { InlineError, PanelEmpty, PanelLoading } from '../shared/AsyncState';
|
||||
import { MonitorReturnBar } from '../shared/MonitorReturnBar';
|
||||
import { PlatformTime } from '../shared/PlatformTime';
|
||||
import { ProtocolTag } from '../shared/ProtocolTag';
|
||||
import { TablePagination } from '../shared/TablePagination';
|
||||
import { WorkspaceCommandBar } from '../shared/WorkspaceCommandBar';
|
||||
import { WorkspaceFilterPanel } from '../shared/WorkspaceFilterPanel';
|
||||
@@ -44,11 +45,6 @@ function HistoryQualityTag({ quality }: { quality: string }) {
|
||||
return <Tag className="v2-history-quality-tag" color={color} type="light" size="small">{historyQualityLabel(quality)}</Tag>;
|
||||
}
|
||||
|
||||
function HistoryProtocolTag({ protocol }: { protocol: string }) {
|
||||
const color = protocol === 'GB32960' ? 'blue' : protocol === 'JT808' ? 'cyan' : protocol === 'YUTONG_MQTT' ? 'violet' : 'grey';
|
||||
return <Tag className="v2-history-protocol-tag" color={color} type="light" size="small">{protocol || '未知来源'}</Tag>;
|
||||
}
|
||||
|
||||
function HistoryTrend({ response, category, loading, error, hasMetrics, expanded, onToggle }: {
|
||||
response?: HistorySeriesResponse;
|
||||
category: string;
|
||||
@@ -162,7 +158,7 @@ function EvidencePanel({ row, metrics, onClose, showHeader = true }: { row?: His
|
||||
<small>{row.qualityReason || '平台未返回质量说明'}</small>
|
||||
</div>
|
||||
<div>
|
||||
<HistoryProtocolTag protocol={row.protocol} />
|
||||
<ProtocolTag className="v2-history-protocol-tag" protocol={row.protocol} />
|
||||
<PlatformTime className="v2-history-time" value={row.deviceTime} />
|
||||
</div>
|
||||
</div><Descriptions className="v2-history-evidence-descriptions" align="left" size="small" data={[
|
||||
@@ -170,7 +166,7 @@ function EvidencePanel({ row, metrics, onClose, showHeader = true }: { row?: His
|
||||
{ key: 'VIN', value: row.vin },
|
||||
{ key: '设备时间', value: <PlatformTime className="v2-history-time" value={row.deviceTime} /> },
|
||||
{ key: '服务时间', value: <PlatformTime className="v2-history-time" value={row.serverTime} /> },
|
||||
{ key: '数据来源', value: <HistoryProtocolTag protocol={row.protocol} /> },
|
||||
{ key: '数据来源', value: <ProtocolTag className="v2-history-protocol-tag" protocol={row.protocol} /> },
|
||||
{ key: '数据质量', value: <HistoryQualityTag quality={row.quality} /> },
|
||||
{ key: '质量原因', value: row.qualityReason || '平台未返回质量说明' }
|
||||
]} />
|
||||
@@ -226,7 +222,7 @@ function HistoryDataTable({ rows, metrics, selectedRowID, onSelect }: { rows: Hi
|
||||
{ title: '车牌', dataIndex: 'plate', width: 110, fixed: 'left' as const, className: 'v2-history-plate-column', render: (value: string) => value || '—' },
|
||||
{ title: '服务时间', dataIndex: 'serverTime', width: 150, render: (value: string) => <PlatformTime className="v2-history-time" value={value} /> },
|
||||
{ title: 'VIN', dataIndex: 'vin', width: 160, render: (value: string) => <span className="v2-history-vin" title={value}>{value}</span> },
|
||||
{ title: '协议', dataIndex: 'protocol', width: 110, render: (value: string) => <HistoryProtocolTag protocol={value} /> },
|
||||
{ title: '协议', dataIndex: 'protocol', width: 118, render: (value: string) => <ProtocolTag className="v2-history-protocol-tag" protocol={value} compact /> },
|
||||
...metrics.map((metric) => ({
|
||||
title: `${metric.label}${metric.unit ? ` (${metric.unit})` : ''}`,
|
||||
dataIndex: metric.key,
|
||||
@@ -485,7 +481,7 @@ export default function HistoryPage() {
|
||||
onKeyDown={scrollHistoryTable}
|
||||
>
|
||||
{mobileLayout
|
||||
? <div className="v2-history-mobile-list">{resultRows.map((row) => <Card key={row.id} className={`v2-history-mobile-card${selectedRow?.id === row.id ? ' is-selected' : ''}`} bodyStyle={{ padding: 0 }}><Button theme="borderless" type="tertiary" className="v2-history-mobile-action" aria-pressed={selectedRow?.id === row.id} aria-expanded={selectedRow?.id === row.id} aria-label={`查看 ${row.plate || row.vin} ${row.deviceTime} 数据详情`} onClick={() => selectRow(row)}><span className="v2-history-mobile-card-content"><header><span><strong>{row.plate || '未绑定车牌'}</strong><small>{row.vin}</small></span><span className={`v2-quality is-${row.quality}`}><i />{historyQualityLabel(row.quality)}</span></header><span className="v2-history-mobile-meta"><PlatformTime className="v2-history-time" value={row.deviceTime} /><HistoryProtocolTag protocol={row.protocol} /></span>{isHealthyHistoryQuality(row.quality) ? null : <small className="v2-history-mobile-quality">{row.qualityReason || '平台未返回质量说明'}</small>}<dl>{visibleMetrics.slice(0, 4).map((metric) => <div key={metric.key}><dt>{metric.label}</dt><dd>{formatHistoryValue(row.values[metric.key], metric)}</dd></div>)}</dl><footer>查看完整详情<IconChevronRight /></footer></span></Button></Card>)}</div>
|
||||
? <div className="v2-history-mobile-list">{resultRows.map((row) => <Card key={row.id} className={`v2-history-mobile-card${selectedRow?.id === row.id ? ' is-selected' : ''}`} bodyStyle={{ padding: 0 }}><Button theme="borderless" type="tertiary" className="v2-history-mobile-action" aria-pressed={selectedRow?.id === row.id} aria-expanded={selectedRow?.id === row.id} aria-label={`查看 ${row.plate || row.vin} ${row.deviceTime} 数据详情`} onClick={() => selectRow(row)}><span className="v2-history-mobile-card-content"><header><span><strong>{row.plate || '未绑定车牌'}</strong><small>{row.vin}</small></span><span className={`v2-quality is-${row.quality}`}><i />{historyQualityLabel(row.quality)}</span></header><span className="v2-history-mobile-meta"><PlatformTime className="v2-history-time" value={row.deviceTime} /><ProtocolTag className="v2-history-protocol-tag" protocol={row.protocol} compact /></span>{isHealthyHistoryQuality(row.quality) ? null : <small className="v2-history-mobile-quality">{row.qualityReason || '平台未返回质量说明'}</small>}<dl>{visibleMetrics.slice(0, 4).map((metric) => <div key={metric.key}><dt>{metric.label}</dt><dd>{formatHistoryValue(row.values[metric.key], metric)}</dd></div>)}</dl><footer>查看完整详情<IconChevronRight /></footer></span></Button></Card>)}</div>
|
||||
: <HistoryDataTable rows={resultRows} metrics={visibleMetrics} selectedRowID={selectedRow?.id} onSelect={selectRow} />}
|
||||
{dataQuery.isPending && keywords.length
|
||||
? <PanelLoading className="v2-history-loading" title="正在加载当前筛选范围的历史数据" description="按车辆、时间和协议整理可追溯证据。" />
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { expect, test } from 'vitest';
|
||||
import { ProtocolTag } from './ProtocolTag';
|
||||
|
||||
test.each([
|
||||
['GB32960', 'GB/T 32960', 'semi-tag-blue-light'],
|
||||
['JT808', 'JT/T 808', 'semi-tag-cyan-light'],
|
||||
['YUTONG_MQTT', '宇通 MQTT', 'semi-tag-violet-light']
|
||||
])('renders %s with its shared display label and source color', (protocol, label, colorClass) => {
|
||||
const view = render(<ProtocolTag protocol={protocol} />);
|
||||
const tag = view.container.querySelector('.v2-protocol-tag.semi-tag');
|
||||
|
||||
expect(screen.getByText(label)).toBeInTheDocument();
|
||||
expect(tag).toHaveClass(colorClass);
|
||||
});
|
||||
|
||||
test('renders a neutral fallback for a missing protocol', () => {
|
||||
const view = render(<ProtocolTag />);
|
||||
|
||||
expect(screen.getByText('未知来源')).toBeInTheDocument();
|
||||
expect(view.container.querySelector('.v2-protocol-tag.semi-tag')).toHaveClass('semi-tag-grey-light');
|
||||
});
|
||||
34
vehicle-data-platform/apps/web/src/v2/shared/ProtocolTag.tsx
Normal file
34
vehicle-data-platform/apps/web/src/v2/shared/ProtocolTag.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Tag } from '@douyinfe/semi-ui';
|
||||
import type { ComponentProps } from 'react';
|
||||
import { protocolDisplayLabel } from '../domain/protocols';
|
||||
|
||||
const PROTOCOL_COLORS: Record<string, ComponentProps<typeof Tag>['color']> = {
|
||||
GB32960: 'blue',
|
||||
JT808: 'cyan',
|
||||
YUTONG_MQTT: 'violet'
|
||||
};
|
||||
|
||||
export function ProtocolTag({
|
||||
protocol,
|
||||
className = '',
|
||||
compact = false,
|
||||
unknownLabel = '未知来源'
|
||||
}: {
|
||||
protocol?: string;
|
||||
className?: string;
|
||||
compact?: boolean;
|
||||
unknownLabel?: string;
|
||||
}) {
|
||||
const normalized = protocol?.trim() ?? '';
|
||||
const classes = ['v2-protocol-tag', compact ? 'is-compact' : '', className].filter(Boolean).join(' ');
|
||||
const label = normalized ? protocolDisplayLabel(normalized) : unknownLabel;
|
||||
|
||||
return <Tag
|
||||
className={classes}
|
||||
color={PROTOCOL_COLORS[normalized] ?? 'grey'}
|
||||
type="light"
|
||||
size="small"
|
||||
>
|
||||
{label}
|
||||
</Tag>;
|
||||
}
|
||||
@@ -16576,3 +16576,83 @@
|
||||
font-size: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Shared protocol identity.
|
||||
* Every evidence surface now presents GB/T 32960, JT/T 808 and 宇通 MQTT
|
||||
* with the same label, source color, spacing and compact behavior.
|
||||
*/
|
||||
.v2-protocol-tag.semi-tag {
|
||||
width: max-content;
|
||||
max-width: 100%;
|
||||
min-height: 22px;
|
||||
flex: 0 0 auto;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
border-radius: 999px;
|
||||
padding-inline: 8px;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
letter-spacing: .01em;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.v2-protocol-tag.is-compact.semi-tag {
|
||||
min-height: 20px;
|
||||
padding-inline: 7px;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Semi UI alert evidence refinement.
|
||||
* Notifications remain accessible but no longer compete with actionable event
|
||||
* counts; protocol evidence stays legible in the table, cards and inspector.
|
||||
*/
|
||||
.v2-alert-context-card .v2-metric-action.is-notice {
|
||||
background: linear-gradient(135deg, #fbfcfe 0%, #f7f8fc 100%);
|
||||
}
|
||||
|
||||
.v2-alert-context-card .v2-metric-action.is-notice strong {
|
||||
color: #697a91;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.v2-alert-event-table .v2-alert-protocol-tag.semi-tag {
|
||||
max-width: 98px;
|
||||
}
|
||||
|
||||
.v2-alert-focus-facts .v2-alert-protocol-tag.semi-tag {
|
||||
max-width: 110px;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content dd:has(.v2-alert-protocol-tag) {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content .v2-alert-protocol-tag.semi-tag {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 680px) {
|
||||
.v2-alert-context-card .v2-metric-action.is-notice strong {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.v2-alert-mobile-card-content dl {
|
||||
grid-template-columns: .95fr .9fr 1.15fr;
|
||||
}
|
||||
|
||||
.v2-alert-inspector.is-sheet .v2-alert-disposition-card .v2-alert-actions {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.v2-alert-inspector.is-sheet .v2-alert-disposition-card .v2-alert-actions > .semi-button {
|
||||
width: 100%;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.v2-alert-inspector.is-sheet .v2-alert-disposition-card .v2-alert-actions > .semi-button.is-primary {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user