refactor(ui): unify semi mobile query workspaces

This commit is contained in:
lingniu
2026-07-19 21:51:03 +08:00
parent f8baaf53ba
commit 2f195e725a
7 changed files with 116 additions and 2 deletions

View File

@@ -240,6 +240,11 @@ test('uses one focused Semi bottom SideSheet for the complete mobile history que
const dialog = await screen.findByRole('dialog', { name: '历史查询范围' });
expect(document.querySelector('.v2-history-filter-sidesheet')).toHaveClass('semi-sidesheet-bottom');
expect(document.querySelector('.v2-history-filter-sidesheet .semi-sidesheet-inner')).toHaveStyle({ height: 'min(82dvh, 700px)' });
const querySummary = within(dialog).getByRole('list', { name: '历史查询范围摘要' });
expect(querySummary).toHaveTextContent('车辆范围待选择最多 5 台车辆');
expect(querySummary).toHaveTextContent('时间范围');
expect(querySummary).toHaveTextContent('上海时区');
expect(querySummary).toHaveTextContent('数据范围位置数据全部来源');
expect(within(dialog).getByPlaceholderText('车牌 / VIN多台用逗号分隔')).toBeInTheDocument();
expect(within(dialog).getByPlaceholderText('开始时间')).toBeInTheDocument();
expect(within(dialog).getByPlaceholderText('结束时间')).toBeInTheDocument();
@@ -249,6 +254,7 @@ test('uses one focused Semi bottom SideSheet for the complete mobile history que
fireEvent.click(within(dialog).getByRole('button', { name: '重置条件' }));
expect(screen.getByRole('dialog', { name: '历史查询范围' })).toBeInTheDocument();
fireEvent.change(within(dialog).getByPlaceholderText('车牌 / VIN多台用逗号分隔'), { target: { value: 'MOBILEVIN' } });
expect(querySummary).toHaveTextContent('车辆范围1 辆最多 5 台车辆');
fireEvent.click(within(dialog).getByRole('button', { name: '应用并查询' }));
await waitFor(() => {

View File

@@ -427,6 +427,11 @@ export default function HistoryPage() {
setSelectedRowRef({ scope: dataScope, id: '' });
}, [dataScope]);
const mobileFiltersOpen = mobileLayout && !filtersCollapsed;
const draftVehicleCount = parseHistoryKeywords(draft.keywords).length;
const draftCategoryLabel = catalogQuery.data?.categories.find((item) => item.key === draft.category)?.label
?? (draft.category === 'raw' ? '原始报文' : draft.category === 'mileage' ? '日里程' : '位置数据');
const draftSourceLabel = draft.protocol || '全部来源';
const draftWindowLabel = `${draft.dateFrom.slice(5, 10)}${draft.dateTo.slice(5, 10)}`;
const historyRangePresets = useMemo(() => [
{ key: 'today' as const, label: '今天', range: historyPresetWindow('today') },
{ key: 'yesterday' as const, label: '昨天', range: historyPresetWindow('yesterday') },
@@ -537,6 +542,25 @@ export default function HistoryPage() {
closeLabel="关闭历史查询范围"
title="筛选历史数据"
description="车辆、时间、数据类型与协议来源"
summaryItems={[
{
label: '车辆范围',
value: draftVehicleCount ? `${draftVehicleCount}` : '待选择',
detail: '最多 5 台车辆',
tone: 'primary'
},
{
label: '时间范围',
value: draftWindowLabel,
detail: '上海时区'
},
{
label: '数据范围',
value: draftCategoryLabel,
detail: draftSourceLabel,
tone: draft.protocol ? 'success' : 'neutral'
}
]}
onCancel={() => setFiltersCollapsed(true)}
secondaryAction={{ label: '重置条件', onClick: resetDraft }}
primaryAction={{ label: '应用并查询', disabled: !parseHistoryKeywords(draft.keywords).length, onClick: applyDraft }}

View File

@@ -284,9 +284,11 @@ test('keeps the mobile vehicle directory primary and applies search from a Semi
const input = screen.getByRole('textbox', { name: '搜索车辆' });
expect(input).toBeVisible();
expect(document.querySelector('.v2-vehicle-mobile-filter-sidesheet')).toBeInTheDocument();
expect(screen.getByRole('list', { name: '车辆搜索摘要' })).toHaveTextContent('授权范围10 辆当前账号可见当前条件全部车辆浏览完整目录快速结果待输入最多展示 6 辆');
expect(screen.getAllByRole('button', { name: /打开 .* 车辆档案/ })).toHaveLength(8);
fireEvent.change(input, { target: { value: items[0].plate } });
expect(await screen.findByRole('listbox')).toHaveAttribute('id', 'v2-vehicle-mobile-search-options');
expect(screen.getByRole('list', { name: '车辆搜索摘要' })).toHaveTextContent(`当前条件${items[0].plate}车牌 / VIN / 终端`);
expect(screen.getAllByRole('button', { name: /打开 .* 车辆档案/ })).toHaveLength(8);
fireEvent.click(screen.getByRole('button', { name: '应用搜索' }));
await waitFor(() => expect(screen.getByRole('button', { name: `修改车辆范围:${items[0].plate} · 10 辆匹配` })).toHaveAttribute('aria-expanded', 'false'));

View File

@@ -201,12 +201,31 @@ export default function VehicleSearchWorkspace() {
<MobileFilterSheet
className="v2-vehicle-mobile-filter-sidesheet"
visible={mobileFiltersOpen}
height="min(68dvh, 560px)"
height="min(72dvh, 610px)"
ariaLabel="车辆搜索"
dialogId="v2-vehicle-mobile-filter-dialog"
closeLabel="关闭车辆搜索"
title="查找车辆"
description="车牌优先,支持 VIN 与终端手机号"
summaryItems={[
{
label: '授权范围',
value: candidates.data ? `${candidates.data.total.toLocaleString('zh-CN')}` : '读取中',
detail: '当前账号可见',
tone: 'primary'
},
{
label: '当前条件',
value: draftKeyword.trim() || '全部车辆',
detail: draftKeyword.trim() ? '车牌 / VIN / 终端' : '浏览完整目录'
},
{
label: '快速结果',
value: deferredDraftKeyword ? mobileCandidates.isFetching ? '查找中' : `${mobileCandidates.data?.total ?? 0}` : '待输入',
detail: '最多展示 6 辆',
tone: deferredDraftKeyword ? 'success' : 'neutral'
}
]}
onCancel={closeMobileFilters}
secondaryAction={{ label: '重置范围', onClick: resetMobileDraft }}
primaryAction={{ label: '应用搜索', onClick: applyMobileFilters }}

View File

@@ -16,6 +16,10 @@ test('renders one shared Semi filter sheet with consistent title, section and ac
closeLabel="关闭测试筛选"
title="筛选车辆"
description="按车辆和状态缩小范围"
summaryItems={[
{ label: '车辆范围', value: '3 辆', detail: '当前已选', tone: 'primary' },
{ label: '数据来源', value: '全部', detail: '3 路协议' }
]}
onCancel={onCancel}
secondaryAction={{ label: '重置条件', onClick: onReset }}
primaryAction={{ label: '应用并查询', onClick: onApply }}
@@ -30,6 +34,7 @@ test('renders one shared Semi filter sheet with consistent title, section and ac
expect(dialog.closest('.semi-sidesheet')).toHaveClass('v2-workspace-filter-sidesheet', 'v2-mobile-filter-sheet', 'test-filter-sheet');
expect(screen.getByText('按车辆和状态缩小范围')).toBeInTheDocument();
expect(screen.getByText('筛选范围')).toBeInTheDocument();
expect(screen.getByRole('list', { name: '测试筛选摘要' })).toHaveTextContent('车辆范围3 辆当前已选数据来源全部3 路协议');
expect(screen.getByText('筛选条件仅在应用后更新当前结果')).toBeInTheDocument();
expect(screen.getByRole('region', { name: '车辆条件' })).toHaveTextContent('支持车牌或 VIN');
fireEvent.click(screen.getByRole('button', { name: '重置条件' }));

View File

@@ -1,6 +1,6 @@
import { IconFilter } from '@douyinfe/semi-icons';
import { type ReactNode } from 'react';
import { WorkspaceSideSheet } from './WorkspaceSideSheet';
import { WorkspaceSideSheet, type WorkspaceSideSheetSummaryItem } from './WorkspaceSideSheet';
type MobileFilterSheetAction = {
label: string;
@@ -18,6 +18,7 @@ type MobileFilterSheetProps = {
closeLabel?: string;
title: string;
description: string;
summaryItems?: WorkspaceSideSheetSummaryItem[];
onCancel: () => void;
secondaryAction?: MobileFilterSheetAction;
primaryAction: MobileFilterSheetAction;
@@ -33,6 +34,7 @@ export function MobileFilterSheet({
closeLabel,
title,
description,
summaryItems = [],
onCancel,
secondaryAction,
primaryAction,
@@ -53,6 +55,7 @@ export function MobileFilterSheet({
description={description}
icon={<IconFilter />}
badge="筛选范围"
summaryItems={summaryItems}
onCancel={onCancel}
footerNote="筛选条件仅在应用后更新当前结果"
secondaryActions={secondaryAction ? [secondaryAction] : []}