refactor: unify guided workspace empty states

This commit is contained in:
lingniu
2026-07-19 12:49:22 +08:00
parent 4e4f383988
commit dffe559160
7 changed files with 367 additions and 14 deletions

View File

@@ -11,7 +11,7 @@ import type { TrackPlaybackEvent, TrackPlaybackResponse, VehicleRow } from '../.
import { protocolDisplayLabel } from '../domain/protocols';
import { buildTrackRailSelection, downloadTrackCsv, formatDuration, sampledEventIndex, TRACK_ADDRESS_SETTLE_MS, trackAddressCoordinate, trackPlaybackInterval, trackPointMileageAvailable, type TrackAddressCoordinate } from '../domain/track';
import { TrackMap } from '../map/TrackMap';
import { InlineError } from '../shared/AsyncState';
import { InlineError, WorkspaceEmptyGuide } from '../shared/AsyncState';
import { MonitorReturnBar } from '../shared/MonitorReturnBar';
import { ProtocolTag } from '../shared/ProtocolTag';
import { SegmentedTabs } from '../shared/SegmentedTabs';
@@ -513,7 +513,18 @@ export default function TrackPage() {
</div>
<p title={addressSettling ? undefined : addressQuery.data?.formattedAddress}>{playing ? '播放中,暂停地址解析' : addressSettling ? '位置已变化,等待地址解析…' : addressQuery.isFetching ? '地址解析中…' : addressQuery.data?.formattedAddress || `${current?.longitude.toFixed(6)}, ${current?.latitude.toFixed(6)}`}</p>
</Card>
</> : <Card className="v2-track-empty-state" bodyStyle={{ padding: 0 }}><Empty image={<IconMapPin />} title="先选择车辆,再开始轨迹回放" description="地图会显示完整路径、停留点、事件点和播放位置。"><Button theme="solid" icon={<IconSearch />} onClick={() => setRailCollapsed(false)}></Button></Empty></Card>}
</> : <Card className="v2-track-empty-state" bodyStyle={{ padding: 0 }}><WorkspaceEmptyGuide
eyebrow="轨迹回放"
icon={<IconMapPin />}
title="先选择车辆,再开始轨迹回放"
description="地图会呈现完整路径、停留点、事件点与逐帧播放位置。"
steps={[
{ icon: <IconSearch />, title: '选择车辆', description: '车牌或 VIN 精确定位' },
{ icon: <IconMapPin />, title: '确认来源', description: '自动选择最佳定位来源' },
{ icon: <IconPlay />, title: '播放核验', description: '逐点查看速度、里程与事件' }
]}
action={<Button theme="solid" icon={<IconSearch />} onClick={() => setRailCollapsed(false)}></Button>}
/></Card>}
{query.isFetching ? <div className="v2-track-loading"><span className="v2-spinner" /></div> : null}
{query.isError ? <div className="v2-track-error"><InlineError message={query.error instanceof Error ? query.error.message : '轨迹查询失败'} onRetry={() => query.refetch()} /></div> : null}