refactor(ui): converge semi mobile vehicle record
This commit is contained in:
@@ -525,7 +525,11 @@ test('keeps protocol telemetry independent and explains mileage semantics', asyn
|
||||
|
||||
test('uses compact Semi telemetry evidence cards on mobile', async () => {
|
||||
layout.mobile = true;
|
||||
vi.spyOn(api, 'vehicleDetail').mockResolvedValue({ ...detail, sources: ['GB32960', 'JT808', 'YUTONG_MQTT'] });
|
||||
vi.spyOn(api, 'vehicleDetail').mockResolvedValue({
|
||||
...detail,
|
||||
profile: { brandName: '测试品牌', modelName: '移动端完整车型名称' } as never,
|
||||
sources: ['GB32960', 'JT808', 'YUTONG_MQTT']
|
||||
});
|
||||
vi.spyOn(api, 'vehicleRealtime').mockResolvedValue({ items: [initialRealtime], total: 1, limit: 1, offset: 0 });
|
||||
vi.spyOn(api, 'latestTelemetry').mockResolvedValue({
|
||||
vin: initialRealtime.vin,
|
||||
@@ -553,6 +557,7 @@ test('uses compact Semi telemetry evidence cards on mobile', async () => {
|
||||
expect(document.querySelector('.v2-telemetry-detail-protocol')).toHaveClass('semi-tag-cyan-light');
|
||||
expect(screen.getByRole('button', { name: '关闭遥测字段详情' })).toBeInTheDocument();
|
||||
expect(document.querySelector('.v2-vehicle-record-page')).toHaveClass('v2-vehicle-record-v3', 'is-mobile-layout');
|
||||
expect(document.querySelector('.v2-identity-model strong')).toHaveAttribute('title', '测试品牌 / 移动端完整车型名称');
|
||||
const mobileActions = screen.getByRole('group', { name: '车辆快捷操作' });
|
||||
expect(mobileActions.querySelectorAll('.semi-button')).toHaveLength(3);
|
||||
expect(mobileActions).toHaveTextContent('切换车辆轨迹回放更多');
|
||||
|
||||
@@ -559,7 +559,7 @@ function VehicleRecord({ detail, liveRealtime, telemetry, telemetryPending, tele
|
||||
</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-model"><small>车辆品牌 / 车型</small><strong title={[detail.profile?.brandName, detail.profile?.modelName].filter(Boolean).join(' / ') || fmt(identity?.oem || realtime?.oem)}>{[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) => <ProtocolTag key={source} protocol={source} compact />) : <Tag color="grey" type="light" size="small">暂无来源</Tag>}</span></span>
|
||||
</span>}
|
||||
actions={<Suspense fallback={null}><VehicleActions actions={actions} mobile={mobileLayout} onSelect={navigate} /></Suspense>}
|
||||
|
||||
@@ -25886,3 +25886,236 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Semi UI mobile vehicle record convergence.
|
||||
* The first viewport keeps identity and four live facts intact, then brings
|
||||
* the map forward by consolidating location, source evidence and section
|
||||
* navigation into compact operational rows.
|
||||
*/
|
||||
@media (max-width: 680px) {
|
||||
.v2-vehicle-record-v3.is-mobile-layout.v2-vehicle-record-page {
|
||||
gap: 6px;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-card.semi-card,
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-source-evidence.semi-card,
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-record-nav.semi-card,
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-single-map-card.semi-card {
|
||||
border-color: #dce5ef;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 16px rgba(31, 53, 80, .04);
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-workspace-command-copy {
|
||||
min-height: 58px;
|
||||
gap: 2px;
|
||||
padding: 6px 9px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-primary {
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-plate {
|
||||
min-height: 32px;
|
||||
border-radius: 8px;
|
||||
padding-inline: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-online-label.semi-tag {
|
||||
min-height: 20px;
|
||||
padding-inline: 6px;
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-vin {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-vin small,
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-vin b {
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-vin .semi-button {
|
||||
width: 24px;
|
||||
min-width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-meta {
|
||||
grid-template-columns: minmax(0, 1fr) minmax(132px, auto);
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-meta > span {
|
||||
min-height: 49px;
|
||||
padding: 5px 8px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-meta small {
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-meta strong {
|
||||
display: -webkit-box;
|
||||
margin-top: 2px;
|
||||
overflow: hidden;
|
||||
font-size: 10px;
|
||||
line-height: 1.25;
|
||||
white-space: normal;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-sources {
|
||||
flex-wrap: nowrap;
|
||||
gap: 3px;
|
||||
margin-top: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-sources .semi-tag {
|
||||
min-height: 18px;
|
||||
padding-inline: 4px;
|
||||
font-size: 7px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-actions {
|
||||
gap: 5px;
|
||||
padding: 5px 7px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-actions > .semi-button {
|
||||
min-height: 36px;
|
||||
border-radius: 8px;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-actions > .semi-button .semi-button-content-left {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-header.v2-vehicle-record-command .v2-identity-actions > .semi-button .semi-button-content-right {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-section > .v2-workspace-panel-header {
|
||||
min-height: 38px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-section .v2-live-report-meta {
|
||||
max-width: 64vw;
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-metric-rail.is-queue.has-context > .semi-card-body {
|
||||
min-height: 96px;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-metric-rail .v2-workspace-metric-list > span,
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-metric-rail .v2-workspace-metric-action.semi-button,
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-metric-rail .v2-workspace-metric-action .semi-button-content {
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-metric-rail .v2-workspace-metric-list > span,
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-metric-rail .v2-workspace-metric-action .semi-button-content {
|
||||
column-gap: 5px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-metric-rail .v2-workspace-metric-list > span > strong,
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-metric-rail .v2-workspace-metric-action .semi-button-content > strong,
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-metric-rail .v2-workspace-metric-list > span.is-secondary > strong,
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-metric-rail .v2-workspace-metric-list > span.is-secondary .v2-workspace-metric-action strong {
|
||||
overflow: visible;
|
||||
font-size: 15px;
|
||||
letter-spacing: -.025em;
|
||||
line-height: 18px;
|
||||
text-overflow: clip;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-metric-rail .v2-workspace-metric-list > span > em,
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-live-metric-rail .v2-workspace-metric-action .semi-button-content > em {
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-card .v2-current-location {
|
||||
min-height: 42px;
|
||||
grid-template-columns: minmax(0, 1.14fr) minmax(124px, .86fr);
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-card .v2-current-location > span {
|
||||
min-height: 42px;
|
||||
gap: 4px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-card .v2-current-location > span + span {
|
||||
border-top: 0;
|
||||
border-left: 1px solid #e4eaf2;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-card .v2-current-location small {
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-card .v2-current-location strong {
|
||||
overflow: hidden;
|
||||
font-size: 9px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-command-card .v2-current-address-action.semi-button {
|
||||
min-height: 28px;
|
||||
border-radius: 7px;
|
||||
padding-inline: 6px;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout > .v2-source-evidence.semi-card .v2-source-evidence-trigger {
|
||||
min-height: 44px;
|
||||
padding: 5px 8px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout > .v2-source-evidence .v2-source-evidence-trigger > div {
|
||||
gap: 1px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout > .v2-source-evidence .v2-source-evidence-trigger strong {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout > .v2-source-evidence .v2-source-evidence-trigger span {
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout > .v2-source-evidence .v2-source-evidence-trigger > .semi-button {
|
||||
min-height: 30px;
|
||||
border-radius: 7px;
|
||||
padding-inline: 8px;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-record-nav .v2-workspace-panel-header {
|
||||
min-height: 44px;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-vehicle-section-nav > .semi-button {
|
||||
min-height: 36px;
|
||||
border-radius: 7px;
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-vehicle-record-v3.is-mobile-layout .v2-single-map-card > .semi-card-body > .v2-workspace-panel-header {
|
||||
min-height: 44px;
|
||||
padding: 5px 9px;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user