feat(web): unify track and history identity

This commit is contained in:
lingniu
2026-07-20 02:15:08 +08:00
parent 537f8d9b45
commit 319728f976
5 changed files with 147 additions and 3 deletions

View File

@@ -138,6 +138,9 @@ test('clears stale rows, charts, and evidence as soon as the history scope chang
expect(view.container.querySelector(`.${className}.semi-card`)).toBeInTheDocument();
}
expect(view.container.querySelector('.v2-history-discovery-shell')).toContainElement(screen.getByLabelText('历史数据查询操作'));
expect(screen.getByLabelText('历史数据查询操作')).toHaveClass('has-identity');
expect(screen.getByLabelText('历史数据查询操作')).toHaveTextContent('历史证据');
expect(screen.getByLabelText('历史数据查询操作').querySelector('.v2-workspace-command-icon.semi-avatar')).toBeInTheDocument();
expect(screen.getByLabelText('历史数据查询操作')).toHaveTextContent('遥测证据检索');
expect(screen.getByLabelText('历史数据查询操作')).toHaveTextContent('07-16 00:00 07-16 05:00');
expect(screen.getByLabelText('历史数据查询操作')).toHaveTextContent('位置数据');

View File

@@ -1,5 +1,5 @@
import { useMutation, useQuery, useQueryClient, type UseQueryResult } from '@tanstack/react-query';
import { IconCalendar, IconChevronRight, IconClose, IconDownload, IconFilter, IconMapPin, IconMore, IconRefresh, IconSearch, IconSetting } from '@douyinfe/semi-icons';
import { IconCalendar, IconChevronRight, IconClose, IconDownload, IconFilter, IconHistory, IconMapPin, IconMore, IconRefresh, IconSearch, IconSetting } from '@douyinfe/semi-icons';
import { Button, Card, CardGroup, Checkbox, Descriptions, Dropdown, Empty, Input, Progress, Select, Spin, Table, Tag, Typography } from '@douyinfe/semi-ui';
import { FormEvent, KeyboardEvent, useCallback, useEffect, useMemo, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
@@ -524,6 +524,8 @@ export default function HistoryPage() {
<WorkspaceCommandBar
className="v2-history-command-bar"
ariaLabel="历史数据查询操作"
eyebrow="历史证据"
icon={<IconHistory />}
title="遥测证据检索"
description="按车辆、时间和协议核验可追溯的历史数据"
status={keywords.length ? `${keywords.length} 辆 · ${(result?.total ?? 0).toLocaleString('zh-CN')}` : '等待查询'}

View File

@@ -176,7 +176,9 @@ 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('轨迹查询任务栏')).toHaveClass('v2-workspace-command-bar', 'v2-track-query-header', 'has-identity');
expect(screen.getByLabelText('轨迹查询任务栏')).toHaveTextContent('轨迹回放');
expect(screen.getByLabelText('轨迹查询任务栏').querySelector('.v2-workspace-command-icon.semi-avatar')).toBeInTheDocument();
expect(screen.getByLabelText('轨迹查询任务栏')).toHaveTextContent('粤A12345');
expect(screen.getByLabelText('轨迹查询任务栏')).toHaveTextContent('3 点');
expect(view.container.querySelector('.v2-track-query-panel')).toHaveClass('is-collapsed');

View File

@@ -1,7 +1,7 @@
import { useQuery } from '@tanstack/react-query';
import {
IconChevronLeft, IconChevronRight, IconClose, IconDownload, IconEyeClosed,
IconEyeOpened, IconList, IconMapPin, IconPause, IconPlay, IconRefresh, IconSearch
IconEyeOpened, IconList, IconMapPin, IconPause, IconPlay, IconRefresh, IconRoute, IconSearch
} from '@douyinfe/semi-icons';
import { Button, Card, Descriptions, Empty, Input, List, Select, Slider, Tag } from '@douyinfe/semi-ui';
import { FormEvent, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
@@ -264,6 +264,8 @@ const TrackRail = memo(function TrackRail({ draft, track, summaryItems, loading,
{showCommandBar ? <WorkspaceCommandBar
className="v2-track-query-header"
ariaLabel="轨迹查询任务栏"
eyebrow="轨迹回放"
icon={<IconRoute />}
title={contextTitle}
description={queryCollapsed ? `${appliedWindow} · ${appliedSource}` : '最长支持连续 7 天'}
status={loading ? '读取中' : track ? `${track.points.length.toLocaleString('zh-CN')}` : '等待查询'}

View File

@@ -26750,3 +26750,138 @@
min-height: 21px;
}
}
/*
* Track and history identity convergence.
* Keep the map and evidence table dominant while making the active task,
* object and query scope immediately recognizable across workspaces.
*/
.v2-track-query-panel .v2-track-query-header.has-identity.v2-workspace-command-bar {
min-height: 62px;
background:
radial-gradient(circle at 12% -80%, rgba(18, 104, 243, .12), transparent 52%),
linear-gradient(108deg, #fff 0%, #fbfdff 100%);
padding: 8px 7px 8px 10px;
}
.v2-track-query-header.has-identity .v2-workspace-command-copy {
flex: 1 1 0;
gap: 7px;
}
.v2-track-query-header.has-identity .v2-workspace-command-icon.semi-avatar {
width: 31px;
height: 31px;
flex-basis: 31px;
border-radius: 9px;
font-size: 13px;
}
.v2-track-query-header.has-identity .v2-workspace-command-stack {
gap: 0;
}
.v2-track-query-header.has-identity .v2-workspace-command-eyebrow {
color: #71839a;
font-size: 7px;
line-height: 9px;
}
.v2-track-query-header.has-identity .v2-workspace-command-title {
color: #263a52;
font-size: 14px;
font-weight: 760;
line-height: 17px;
}
.v2-track-query-header.has-identity .v2-workspace-command-description {
color: #8492a4;
font-size: 8px;
line-height: 11px;
}
.v2-track-query-header.has-identity .v2-workspace-command-actions {
flex: 0 0 auto;
gap: 2px;
}
.v2-track-query-header.has-identity .v2-workspace-command-actions > .semi-tag {
border-color: rgba(18, 104, 243, .08);
background: #eef5ff;
color: #245da8;
}
.v2-history-discovery-shell > .v2-history-command-bar.has-identity {
min-height: 58px;
background:
radial-gradient(circle at 91% -100%, rgba(18, 104, 243, .1), transparent 42%),
linear-gradient(105deg, #fff 0%, #fbfdff 100%);
padding: 8px 10px 8px 12px;
}
.v2-history-command-bar.has-identity .v2-workspace-command-copy {
min-width: 240px;
}
.v2-history-command-bar.has-identity .v2-workspace-command-icon.semi-avatar {
width: 34px;
height: 34px;
flex-basis: 34px;
border-radius: 10px;
font-size: 14px;
}
.v2-history-command-bar.has-identity .v2-workspace-command-stack {
gap: 0;
}
.v2-history-command-bar.has-identity .v2-workspace-command-title {
color: #263a52;
font-size: 14px;
font-weight: 760;
line-height: 18px;
}
.v2-history-command-bar.has-identity .v2-workspace-command-description {
color: #8290a3;
font-size: 9px;
line-height: 12px;
}
.v2-history-command-bar.has-identity .v2-workspace-command-actions > .semi-tag {
border-color: rgba(18, 104, 243, .08);
background: #eef5ff;
color: #245da8;
}
@media (min-width: 681px) and (max-width: 980px) {
.v2-history-command-bar.has-identity .v2-workspace-command-copy {
min-width: 190px;
}
.v2-history-command-bar.has-identity .v2-workspace-command-description {
display: none;
}
}
@media (max-width: 680px) {
.v2-history-discovery-shell > .v2-history-command-bar.has-identity {
min-height: 54px;
padding: 7px 9px;
}
.v2-history-command-bar.has-identity .v2-workspace-command-copy {
min-width: 0;
}
.v2-history-command-bar.has-identity .v2-workspace-command-icon.semi-avatar {
width: 32px;
height: 32px;
flex-basis: 32px;
}
.v2-history-command-bar.has-identity .v2-workspace-command-description,
.v2-history-command-bar.has-identity .v2-workspace-command-meta {
display: none;
}
}