refine Semi UI track and vehicle workspaces
This commit is contained in:
@@ -173,6 +173,8 @@ test('renders a map-first replay workspace and connects stop, event, and panel i
|
||||
|
||||
expect((await screen.findAllByText('粤A12345')).length).toBeGreaterThan(0);
|
||||
expect(view.container.querySelector('.v2-track-rail-shell.semi-card')).toBeInTheDocument();
|
||||
expect(screen.getByLabelText('轨迹查询任务栏')).toHaveClass('v2-workspace-command-bar', 'v2-track-query-header');
|
||||
expect(screen.getByLabelText('轨迹查询任务栏')).toHaveTextContent('3 点');
|
||||
expect(view.container.querySelector('.v2-track-query-panel')).toHaveClass('is-collapsed');
|
||||
expect(view.container.querySelector('.v2-track-rail-result')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: '修改条件' })).toHaveAttribute('aria-expanded', 'false');
|
||||
|
||||
@@ -15,6 +15,7 @@ import { MonitorReturnBar } from '../shared/MonitorReturnBar';
|
||||
import { SegmentedTabs } from '../shared/SegmentedTabs';
|
||||
import { VehicleCandidateList } from '../shared/VehicleCandidateList';
|
||||
import { mergeVehicleCandidates } from '../shared/vehicleCandidates';
|
||||
import { WorkspaceCommandBar } from '../shared/WorkspaceCommandBar';
|
||||
import { WorkspacePanelHeader } from '../shared/WorkspacePanelHeader';
|
||||
import { QUERY_MEMORY } from '../queryPolicy';
|
||||
import { monitorReturnFromParams, preserveMonitorReturn } from '../routing/monitorContext';
|
||||
@@ -197,10 +198,13 @@ const TrackRail = memo(function TrackRail({ draft, track, loading, activeStopInd
|
||||
return <aside className="v2-track-rail">
|
||||
<Card className="v2-track-rail-shell" bodyStyle={{ padding: 0 }}>
|
||||
<section className={`v2-track-query-panel${queryCollapsed ? ' is-collapsed' : ''}`}>
|
||||
<WorkspacePanelHeader
|
||||
<WorkspaceCommandBar
|
||||
className="v2-track-query-header"
|
||||
ariaLabel="轨迹查询任务栏"
|
||||
title="轨迹查询"
|
||||
description={queryCollapsed ? `${appliedWindow} · ${appliedSource}` : '最长支持连续 7 天'}
|
||||
status={loading ? '读取中' : track ? `${track.points.length.toLocaleString('zh-CN')} 点` : '等待查询'}
|
||||
statusColor={loading ? 'blue' : track ? 'green' : 'grey'}
|
||||
actions={<>
|
||||
<Button
|
||||
className="v2-track-query-toggle"
|
||||
|
||||
@@ -79,6 +79,9 @@ test('polls lightweight single-vehicle realtime data and passes its report inter
|
||||
]));
|
||||
const commandCard = view.container.querySelector('.v2-identity-band');
|
||||
expect(commandCard).toHaveClass('semi-card', 'v2-vehicle-command-card', 'v2-live-overview');
|
||||
expect(screen.getByLabelText('单车任务栏')).toHaveClass('v2-workspace-command-bar', 'v2-vehicle-record-command');
|
||||
expect(screen.getByLabelText('单车任务栏')).toHaveTextContent('粤A12345');
|
||||
expect(screen.getByLabelText('单车任务栏')).toHaveTextContent('LTEST000000000001');
|
||||
expect(screen.getByRole('list', { name: '车辆实时指标' })).toHaveClass('v2-live-grid');
|
||||
expect(commandCard?.querySelectorAll('.v2-live-grid > [role="listitem"]')).toHaveLength(6);
|
||||
expect(commandCard?.querySelector('.v2-live-grid > div:first-child')).toHaveTextContent('速度');
|
||||
|
||||
@@ -20,6 +20,7 @@ import { MonitorReturnBar } from '../shared/MonitorReturnBar';
|
||||
import { PlatformTime } from '../shared/PlatformTime';
|
||||
import { SegmentedTabs } from '../shared/SegmentedTabs';
|
||||
import { VehicleSourceEvidencePanel } from '../shared/VehicleSourceEvidencePanel';
|
||||
import { WorkspaceCommandBar } from '../shared/WorkspaceCommandBar';
|
||||
import { WorkspacePanelHeader } from '../shared/WorkspacePanelHeader';
|
||||
import { monitorReturnFromParams, withMonitorReturn } from '../routing/monitorContext';
|
||||
import { useMobileLayout } from '../hooks/useMobileLayout';
|
||||
@@ -456,20 +457,22 @@ function VehicleRecord({ detail, liveRealtime, telemetry, telemetryPending, tele
|
||||
return <div ref={recordRootRef} className={`v2-vehicle-record-page${mobileLayout ? ' is-mobile-layout' : ''}`} tabIndex={-1} aria-label={`${fmt(identity?.plate || realtime?.plate)} 车辆档案`}>
|
||||
<MonitorReturnBar />
|
||||
<Card className="v2-identity-band v2-record-card v2-live-card v2-live-overview v2-vehicle-command-card" bodyStyle={{ padding: 0 }}>
|
||||
<div className="v2-vehicle-command-header">
|
||||
<div className="v2-identity-primary">
|
||||
<WorkspaceCommandBar
|
||||
className="v2-vehicle-command-header v2-vehicle-record-command"
|
||||
ariaLabel="单车任务栏"
|
||||
title={<span className="v2-identity-primary">
|
||||
<span className="v2-plate"><IconBox />{fmt(identity?.plate || realtime?.plate)}</span>
|
||||
<Tag className={`v2-online-label ${realtime?.online ? 'is-online' : ''}`} color={realtime?.online ? 'green' : 'grey'} size="small">{realtime?.online ? '在线' : '离线'}</Tag>
|
||||
<span className="v2-identity-vin"><small>VIN</small><b>{detail.vin}</b><Button theme="borderless" aria-label="复制 VIN" title="复制 VIN" icon={<IconCopy />} onClick={() => navigator.clipboard?.writeText(detail.vin)} /></span>
|
||||
</div>
|
||||
<div className="v2-identity-meta">
|
||||
<div><small>车辆品牌 / 车型</small><strong>{[detail.profile?.brandName, detail.profile?.modelName].filter(Boolean).join(' / ') || fmt(identity?.oem || realtime?.oem)}</strong></div>
|
||||
<div><small>可用数据来源</small><div className="v2-identity-sources">{detail.sources.length ? detail.sources.map((source) => <Tag key={source} color="blue" type="light" size="small">{source}</Tag>) : <Tag color="grey" type="light" size="small">暂无来源</Tag>}</div></div>
|
||||
</div>
|
||||
<div className="v2-identity-actions" role="group" aria-label="车辆快捷操作">
|
||||
</span>}
|
||||
description={<span className="v2-identity-vin"><small>VIN</small><b>{detail.vin}</b><Button theme="borderless" aria-label="复制 VIN" title="复制 VIN" icon={<IconCopy />} onClick={() => navigator.clipboard?.writeText(detail.vin)} /></span>}
|
||||
meta={<span className="v2-identity-meta">
|
||||
<span className="v2-identity-model"><small>车辆品牌 / 车型</small><strong>{[detail.profile?.brandName, detail.profile?.modelName].filter(Boolean).join(' / ') || fmt(identity?.oem || realtime?.oem)}</strong></span>
|
||||
<span className="v2-identity-source-context"><small>可用数据来源</small><span className="v2-identity-sources">{detail.sources.length ? detail.sources.map((source) => <Tag key={source} color="blue" type="light" size="small">{source}</Tag>) : <Tag color="grey" type="light" size="small">暂无来源</Tag>}</span></span>
|
||||
</span>}
|
||||
actions={<div className="v2-identity-actions" role="group" aria-label="车辆快捷操作">
|
||||
{actions.map((action) => <Button key={action.key} theme="light" type={action.type} icon={action.icon} aria-label={action.label} onClick={() => navigate(action.to)}>{action.label}</Button>)}
|
||||
</div>
|
||||
</div>
|
||||
</div>}
|
||||
/>
|
||||
<section className="v2-vehicle-live-section" aria-labelledby="vehicle-live-heading">
|
||||
<WorkspacePanelHeader
|
||||
title={<span id="vehicle-live-heading">最新上报</span>}
|
||||
|
||||
Reference in New Issue
Block a user