refine Semi UI vehicle discovery workspace
This commit is contained in:
@@ -137,7 +137,7 @@ test('shows deduplicated Semi vehicle candidates and opens the selected VIN', as
|
|||||||
const vehicles = vi.spyOn(api, 'vehicles').mockResolvedValue({
|
const vehicles = vi.spyOn(api, 'vehicles').mockResolvedValue({
|
||||||
items: [candidate, { ...candidate }],
|
items: [candidate, { ...candidate }],
|
||||||
total: 2,
|
total: 2,
|
||||||
limit: 8,
|
limit: 12,
|
||||||
offset: 0
|
offset: 0
|
||||||
});
|
});
|
||||||
vi.spyOn(api, 'vehicleDetail').mockResolvedValue(detail);
|
vi.spyOn(api, 'vehicleDetail').mockResolvedValue(detail);
|
||||||
@@ -147,15 +147,16 @@ test('shows deduplicated Semi vehicle candidates and opens the selected VIN', as
|
|||||||
|
|
||||||
const view = render(<QueryClientProvider client={client}><MemoryRouter initialEntries={['/vehicles']} future={ROUTER_FUTURE}><Routes><Route path="/vehicles" element={<VehiclePage />} /><Route path="/vehicles/:vin" element={<VehiclePage />} /></Routes></MemoryRouter></QueryClientProvider>);
|
const view = render(<QueryClientProvider client={client}><MemoryRouter initialEntries={['/vehicles']} future={ROUTER_FUTURE}><Routes><Route path="/vehicles" element={<VehiclePage />} /><Route path="/vehicles/:vin" element={<VehiclePage />} /></Routes></MemoryRouter></QueryClientProvider>);
|
||||||
|
|
||||||
const capabilitySummary = screen.getByLabelText('可查询的数据范围');
|
expect(screen.getByRole('heading', { name: '车辆查询', level: 2 })).toBeInTheDocument();
|
||||||
expect(capabilitySummary).toHaveTextContent('统一身份');
|
expect(screen.getByRole('heading', { name: '车辆定位', level: 5 }).closest('.semi-card')).toHaveClass('v2-vehicle-query-panel', 'v2-workspace-filter-panel');
|
||||||
expect(capabilitySummary).toHaveTextContent('实时状态');
|
|
||||||
expect(capabilitySummary).toHaveTextContent('来源证据');
|
|
||||||
const input = screen.getByRole('textbox', { name: '搜索车辆' });
|
const input = screen.getByRole('textbox', { name: '搜索车辆' });
|
||||||
expect(input).toHaveAttribute('aria-expanded', 'false');
|
expect(input).toHaveAttribute('aria-expanded', 'false');
|
||||||
expect(input).toHaveAttribute('aria-controls', 'v2-vehicle-search-options');
|
expect(input).toHaveAttribute('aria-controls', 'v2-vehicle-search-options');
|
||||||
expect(view.container.querySelector('.v2-vehicle-search-options')).not.toBeInTheDocument();
|
expect(view.container.querySelector('.v2-vehicle-search-options')).not.toBeInTheDocument();
|
||||||
await waitFor(() => expect(vehicles).toHaveBeenCalledTimes(1));
|
await waitFor(() => expect(vehicles).toHaveBeenCalledTimes(1));
|
||||||
|
const initialQuery = vehicles.mock.calls[0]?.[0];
|
||||||
|
expect(initialQuery).toBeDefined();
|
||||||
|
expect(initialQuery!.get('limit')).toBe('12');
|
||||||
expect(screen.getByRole('heading', { name: '最近上报车辆', level: 5 })).toBeInTheDocument();
|
expect(screen.getByRole('heading', { name: '最近上报车辆', level: 5 })).toBeInTheDocument();
|
||||||
expect(await screen.findByText('当前显示 1 辆')).toBeInTheDocument();
|
expect(await screen.findByText('当前显示 1 辆')).toBeInTheDocument();
|
||||||
expect(screen.getAllByRole('listitem', { name: `打开 ${initialRealtime.plate} 车辆档案` })).toHaveLength(1);
|
expect(screen.getAllByRole('listitem', { name: `打开 ${initialRealtime.plate} 车辆档案` })).toHaveLength(1);
|
||||||
@@ -180,6 +181,34 @@ test('shows deduplicated Semi vehicle candidates and opens the selected VIN', as
|
|||||||
workspace.remove();
|
workspace.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('defaults to a compact mobile vehicle directory and keeps eight recent vehicles', async () => {
|
||||||
|
layout.mobile = true;
|
||||||
|
const items = Array.from({ length: 10 }, (_, index) => ({
|
||||||
|
vin: `LTEST${String(index).padStart(12, '0')}`,
|
||||||
|
plate: `粤A${String(index).padStart(5, '0')}`,
|
||||||
|
phone: '',
|
||||||
|
oem: '测试品牌',
|
||||||
|
protocol: index % 2 ? 'JT808' : 'GB32960',
|
||||||
|
online: index < 6,
|
||||||
|
lastSeen: `2026-07-16 10:00:${String(index).padStart(2, '0')}`,
|
||||||
|
locationText: '广东省广州市',
|
||||||
|
bindingScore: 100
|
||||||
|
}));
|
||||||
|
vi.spyOn(api, 'vehicles').mockResolvedValue({ items, total: 10, limit: 12, offset: 0 });
|
||||||
|
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
||||||
|
|
||||||
|
const view = render(<QueryClientProvider client={client}><MemoryRouter initialEntries={['/vehicles']} future={ROUTER_FUTURE}><Routes><Route path="/vehicles" element={<VehiclePage />} /></Routes></MemoryRouter></QueryClientProvider>);
|
||||||
|
|
||||||
|
expect(await screen.findByText('当前显示 8 辆')).toBeInTheDocument();
|
||||||
|
expect(screen.getAllByRole('listitem', { name: /打开 .* 车辆档案/ })).toHaveLength(8);
|
||||||
|
expect(view.container.querySelector('.v2-vehicle-query-panel')).toHaveClass('is-mobile-collapsed');
|
||||||
|
const toggle = screen.getByRole('button', { name: '修改车辆定位:10 辆授权车辆' });
|
||||||
|
expect(toggle).toHaveAttribute('aria-expanded', 'false');
|
||||||
|
fireEvent.click(toggle);
|
||||||
|
expect(view.container.querySelector('.v2-vehicle-query-panel')).not.toHaveClass('is-mobile-collapsed');
|
||||||
|
expect(screen.getByRole('textbox', { name: '搜索车辆' })).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
test('keeps the monitor return on the vehicle page and its nested investigation actions', async () => {
|
test('keeps the monitor return on the vehicle page and its nested investigation actions', async () => {
|
||||||
vi.spyOn(api, 'vehicleDetail').mockResolvedValue(detail);
|
vi.spyOn(api, 'vehicleDetail').mockResolvedValue(detail);
|
||||||
vi.spyOn(api, 'vehicleRealtime').mockResolvedValue({ items: [initialRealtime], total: 1, limit: 1, offset: 0 });
|
vi.spyOn(api, 'vehicleRealtime').mockResolvedValue({ items: [initialRealtime], total: 1, limit: 1, offset: 0 });
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||||
import {
|
import {
|
||||||
IconAlarm, IconArrowRight, IconBox, IconCalendar, IconClock, IconCopy,
|
IconAlarm, IconArrowRight, IconBox, IconCalendar, IconClock, IconCopy,
|
||||||
IconChevronRight, IconMapPin, IconSearch, IconTickCircle
|
IconChevronRight, IconMapPin, IconRefresh, IconSearch, IconTickCircle
|
||||||
} from '@douyinfe/semi-icons';
|
} from '@douyinfe/semi-icons';
|
||||||
import { Button, Card, Descriptions, Empty, Input, List, Select, Table, Tag, Typography } from '@douyinfe/semi-ui';
|
import { Button, Card, Descriptions, Empty, Input, List, Select, Table, Tag } from '@douyinfe/semi-ui';
|
||||||
import { FormEvent, lazy, Suspense, useDeferredValue, useEffect, useMemo, useRef, useState } from 'react';
|
import { FormEvent, lazy, Suspense, useDeferredValue, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { Link, useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
import { Link, useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
||||||
import { api } from '../../api/client';
|
import { api } from '../../api/client';
|
||||||
@@ -17,10 +17,12 @@ import { isValidAMapCoordinate } from '../../integrations/amap';
|
|||||||
import { FleetMap } from '../map/FleetMap';
|
import { FleetMap } from '../map/FleetMap';
|
||||||
import { InlineError, PageLoading } from '../shared/AsyncState';
|
import { InlineError, PageLoading } from '../shared/AsyncState';
|
||||||
import { MonitorReturnBar } from '../shared/MonitorReturnBar';
|
import { MonitorReturnBar } from '../shared/MonitorReturnBar';
|
||||||
|
import { PageHeader } from '../shared/PageHeader';
|
||||||
import { SegmentedTabs } from '../shared/SegmentedTabs';
|
import { SegmentedTabs } from '../shared/SegmentedTabs';
|
||||||
import { VehicleCandidateList } from '../shared/VehicleCandidateList';
|
import { VehicleCandidateList } from '../shared/VehicleCandidateList';
|
||||||
import { mergeVehicleCandidates } from '../shared/vehicleCandidates';
|
import { mergeVehicleCandidates } from '../shared/vehicleCandidates';
|
||||||
import { VehicleSourceEvidencePanel } from '../shared/VehicleSourceEvidencePanel';
|
import { VehicleSourceEvidencePanel } from '../shared/VehicleSourceEvidencePanel';
|
||||||
|
import { WorkspaceFilterPanel } from '../shared/WorkspaceFilterPanel';
|
||||||
import { WorkspacePanelHeader } from '../shared/WorkspacePanelHeader';
|
import { WorkspacePanelHeader } from '../shared/WorkspacePanelHeader';
|
||||||
import { monitorReturnFromParams, withMonitorReturn } from '../routing/monitorContext';
|
import { monitorReturnFromParams, withMonitorReturn } from '../routing/monitorContext';
|
||||||
import { useMobileLayout } from '../hooks/useMobileLayout';
|
import { useMobileLayout } from '../hooks/useMobileLayout';
|
||||||
@@ -56,10 +58,11 @@ function VehicleSearch() {
|
|||||||
const [keyword, setKeyword] = useState('');
|
const [keyword, setKeyword] = useState('');
|
||||||
const [syncOpen, setSyncOpen] = useState(false);
|
const [syncOpen, setSyncOpen] = useState(false);
|
||||||
const [candidatesOpen, setCandidatesOpen] = useState(false);
|
const [candidatesOpen, setCandidatesOpen] = useState(false);
|
||||||
|
const [filtersCollapsed, setFiltersCollapsed] = useState(mobileLayout);
|
||||||
const closeTimerRef = useRef<number>();
|
const closeTimerRef = useRef<number>();
|
||||||
const deferredKeyword = useDeferredValue(keyword.trim());
|
const deferredKeyword = useDeferredValue(keyword.trim());
|
||||||
const candidateParams = useMemo(() => {
|
const candidateParams = useMemo(() => {
|
||||||
const params = new URLSearchParams({ limit: '8', offset: '0' });
|
const params = new URLSearchParams({ limit: '12', offset: '0' });
|
||||||
if (deferredKeyword) params.set('keyword', deferredKeyword);
|
if (deferredKeyword) params.set('keyword', deferredKeyword);
|
||||||
return params;
|
return params;
|
||||||
}, [deferredKeyword]);
|
}, [deferredKeyword]);
|
||||||
@@ -70,7 +73,7 @@ function VehicleSearch() {
|
|||||||
gcTime: QUERY_MEMORY.optionGcTime
|
gcTime: QUERY_MEMORY.optionGcTime
|
||||||
});
|
});
|
||||||
const options = useMemo(() => mergeVehicleCandidates(candidates.data?.items ?? []), [candidates.data?.items]);
|
const options = useMemo(() => mergeVehicleCandidates(candidates.data?.items ?? []), [candidates.data?.items]);
|
||||||
const quickVehicles = useMemo(() => options.slice(0, mobileLayout ? 5 : 6), [mobileLayout, options]);
|
const quickVehicles = useMemo(() => options.slice(0, mobileLayout ? 8 : 12), [mobileLayout, options]);
|
||||||
useEffect(() => () => window.clearTimeout(closeTimerRef.current), []);
|
useEffect(() => () => window.clearTimeout(closeTimerRef.current), []);
|
||||||
const openCandidates = () => {
|
const openCandidates = () => {
|
||||||
window.clearTimeout(closeTimerRef.current);
|
window.clearTimeout(closeTimerRef.current);
|
||||||
@@ -94,16 +97,27 @@ function VehicleSearch() {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
openVehicle(keyword);
|
openVehicle(keyword);
|
||||||
};
|
};
|
||||||
|
const vehicleScope = candidates.data ? `${candidates.data.total.toLocaleString('zh-CN')} 辆授权` : '授权范围';
|
||||||
return <section className={`v2-vehicle-search-page${syncOpen ? ' has-sync-panel' : ''}${candidatesOpen ? ' has-candidates' : ''}`}>
|
return <section className={`v2-vehicle-search-page${syncOpen ? ' has-sync-panel' : ''}${candidatesOpen ? ' has-candidates' : ''}`}>
|
||||||
<Card className="v2-vehicle-search-card">
|
<PageHeader
|
||||||
<div className="v2-vehicle-search-intro">
|
title="车辆查询"
|
||||||
<span className="v2-search-hero-icon"><IconBox size="extra-large" /></span>
|
description="通过车牌、VIN 或终端手机号定位车辆,进入统一数字档案"
|
||||||
<div>
|
status={candidates.isPending ? '正在读取授权范围' : vehicleScope}
|
||||||
<Typography.Title heading={2}>查询单车数字档案</Typography.Title>
|
statusColor={candidates.isError ? 'red' : 'blue'}
|
||||||
<Typography.Text type="secondary">通过车牌、VIN 或终端手机号定位车辆,并查看统一身份、实时状态和来源证据。</Typography.Text>
|
actions={canAdminister(session) ? <Button theme="light" onClick={() => setSyncOpen((value) => !value)}>{syncOpen ? '收起主档同步' : '批量同步主档'}</Button> : null}
|
||||||
</div>
|
/>
|
||||||
</div>
|
<WorkspaceFilterPanel
|
||||||
<form className="v2-vehicle-search-form" onSubmit={submit}>
|
className="v2-vehicle-query-panel"
|
||||||
|
title="车辆定位"
|
||||||
|
description="车牌优先、VIN 辅助,支持终端手机号精确定位"
|
||||||
|
mobileSummary={deferredKeyword ? `正在查找 ${deferredKeyword}` : candidates.data ? `${candidates.data.total.toLocaleString('zh-CN')} 辆授权车辆` : '正在读取授权范围'}
|
||||||
|
expanded={!filtersCollapsed}
|
||||||
|
status={deferredKeyword ? candidates.isFetching ? '正在查找' : `${options.length} 辆匹配` : vehicleScope}
|
||||||
|
statusColor={deferredKeyword ? 'blue' : 'grey'}
|
||||||
|
collapsedLabel="修改"
|
||||||
|
onToggle={() => setFiltersCollapsed((value) => !value)}
|
||||||
|
>
|
||||||
|
<form className={`v2-vehicle-search-form${filtersCollapsed ? ' is-mobile-collapsed' : ''}`} onSubmit={submit}>
|
||||||
<div className={`v2-vehicle-search-picker${candidatesOpen ? ' is-open' : ''}`}>
|
<div className={`v2-vehicle-search-picker${candidatesOpen ? ' is-open' : ''}`}>
|
||||||
<Input
|
<Input
|
||||||
aria-label="搜索车辆"
|
aria-label="搜索车辆"
|
||||||
@@ -135,18 +149,13 @@ function VehicleSearch() {
|
|||||||
onSelect={(vehicle) => openVehicle(vehicle.vin)}
|
onSelect={(vehicle) => openVehicle(vehicle.vin)}
|
||||||
/> : null}
|
/> : null}
|
||||||
</form>
|
</form>
|
||||||
<div className="v2-vehicle-search-capabilities" aria-label="可查询的数据范围">
|
</WorkspaceFilterPanel>
|
||||||
<span><IconBox /><b>统一身份</b><small>车牌、VIN 与车辆主档</small></span>
|
|
||||||
<span><IconClock /><b>实时状态</b><small>位置、里程与最新上报</small></span>
|
|
||||||
<span><IconTickCircle /><b>来源证据</b><small>协议质量与字段明细</small></span>
|
|
||||||
</div>
|
|
||||||
{canAdminister(session) ? <Button className="v2-profile-sync-open" theme="borderless" onClick={() => setSyncOpen((value) => !value)}>{syncOpen ? '收起批量同步' : '批量同步主档'}</Button> : null}
|
|
||||||
</Card>
|
|
||||||
<Card className="v2-vehicle-recent-card" bodyStyle={{ padding: 0 }}>
|
<Card className="v2-vehicle-recent-card" bodyStyle={{ padding: 0 }}>
|
||||||
<WorkspacePanelHeader
|
<WorkspacePanelHeader
|
||||||
title={deferredKeyword ? '匹配车辆快捷入口' : '最近上报车辆'}
|
title={deferredKeyword ? '匹配车辆快捷入口' : '最近上报车辆'}
|
||||||
description={deferredKeyword ? '按当前搜索条件展示,可直接进入车辆数字档案' : '按照最新上报时间排列,无需搜索即可继续查看'}
|
description={deferredKeyword ? '按当前搜索条件展示,可直接进入车辆数字档案' : '按照最新上报时间排列,无需搜索即可继续查看'}
|
||||||
meta={<Tag color={deferredKeyword ? 'blue' : 'grey'} type="light" size="small">{candidates.data ? `当前显示 ${formatZhNumber(quickVehicles.length)} 辆` : '授权范围'}</Tag>}
|
meta={<Tag color={deferredKeyword ? 'blue' : 'grey'} type="light" size="small">{candidates.data ? `当前显示 ${formatZhNumber(quickVehicles.length)} 辆` : '授权范围'}</Tag>}
|
||||||
|
actions={<Button theme="borderless" type="tertiary" size="small" icon={<IconRefresh />} loading={candidates.isFetching} onClick={() => candidates.refetch()}>刷新</Button>}
|
||||||
/>
|
/>
|
||||||
{candidates.isFetching && !candidates.data
|
{candidates.isFetching && !candidates.data
|
||||||
? <div className="v2-vehicle-recent-state" role="status"><span className="v2-spinner" /><span>正在读取授权车辆…</span></div>
|
? <div className="v2-vehicle-recent-state" role="status"><span className="v2-spinner" /><span>正在读取授权车辆…</span></div>
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ describe('V2 production entry', () => {
|
|||||||
expect(source).toContain("from '@douyinfe/semi-ui'");
|
expect(source).toContain("from '@douyinfe/semi-ui'");
|
||||||
expect(source).toContain('<Button');
|
expect(source).toContain('<Button');
|
||||||
}
|
}
|
||||||
for (const name of ['HistoryPage', 'AlertsPage', 'AccessPage', 'UsersPage', 'OperationsPage']) {
|
for (const name of ['VehiclePage', 'HistoryPage', 'AlertsPage', 'AccessPage', 'UsersPage', 'OperationsPage']) {
|
||||||
expect(corePageSources[name]).toContain("from '../shared/PageHeader'");
|
expect(corePageSources[name]).toContain("from '../shared/PageHeader'");
|
||||||
expect(corePageSources[name]).toContain('<PageHeader');
|
expect(corePageSources[name]).toContain('<PageHeader');
|
||||||
}
|
}
|
||||||
@@ -442,7 +442,7 @@ describe('V2 production entry', () => {
|
|||||||
expect(v2Styles).toContain('.v2-track-current-card.semi-card { top: auto; right: 8px; bottom: 126px; left: 8px; width: auto; height: auto;');
|
expect(v2Styles).toContain('.v2-track-current-card.semi-card { top: auto; right: 8px; bottom: 126px; left: 8px; width: auto; height: auto;');
|
||||||
expect(workspaceFilterPanelSource).toContain("from './MobileFilterToggle'");
|
expect(workspaceFilterPanelSource).toContain("from './MobileFilterToggle'");
|
||||||
expect(workspaceFilterPanelSource).toContain('<MobileFilterToggle');
|
expect(workspaceFilterPanelSource).toContain('<MobileFilterToggle');
|
||||||
for (const name of ['HistoryPage', 'AlertsPage', 'AccessPage', 'StatisticsPage', 'UsersPage', 'OperationsPage']) {
|
for (const name of ['VehiclePage', 'HistoryPage', 'AlertsPage', 'AccessPage', 'StatisticsPage', 'UsersPage', 'OperationsPage']) {
|
||||||
expect(corePageSources[name]).toContain("from '../shared/WorkspaceFilterPanel'");
|
expect(corePageSources[name]).toContain("from '../shared/WorkspaceFilterPanel'");
|
||||||
expect(corePageSources[name]).toContain('<WorkspaceFilterPanel');
|
expect(corePageSources[name]).toContain('<WorkspaceFilterPanel');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1422,48 +1422,73 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Semi UI convergence: vehicle discovery and track replay. */
|
/* Semi UI convergence: vehicle discovery and track replay. */
|
||||||
.v2-vehicle-search-capabilities {
|
.v2-vehicle-search-page {
|
||||||
display: grid;
|
align-content: start;
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
place-items: start center;
|
||||||
gap: 8px;
|
gap: 12px;
|
||||||
margin-top: 18px;
|
overflow: auto;
|
||||||
|
padding: 16px var(--v2-page-gutter) 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v2-vehicle-search-capabilities > span {
|
.v2-vehicle-search-page > .v2-page-heading,
|
||||||
display: grid;
|
.v2-vehicle-search-page > .v2-mobile-filter-toggle,
|
||||||
min-width: 0;
|
.v2-vehicle-search-page > .v2-vehicle-query-panel,
|
||||||
grid-template-columns: 30px minmax(0, 1fr);
|
.v2-vehicle-search-page > .v2-vehicle-recent-card,
|
||||||
grid-template-rows: auto auto;
|
.v2-vehicle-search-page > .v2-profile-sync-panel {
|
||||||
align-items: center;
|
box-sizing: border-box;
|
||||||
gap: 2px 9px;
|
width: min(1280px, 100%);
|
||||||
border: 1px solid #e2e9f2;
|
}
|
||||||
border-radius: 10px;
|
|
||||||
|
.v2-vehicle-query-panel.v2-workspace-filter-panel.semi-card {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-vehicle-query-panel .v2-vehicle-search-form {
|
||||||
|
height: auto;
|
||||||
|
min-height: 60px;
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
border-top: 1px solid #e7edf4;
|
||||||
|
border-radius: 0 0 12px 12px;
|
||||||
background: #fbfcfe;
|
background: #fbfcfe;
|
||||||
padding: 10px 12px;
|
padding: 8px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v2-vehicle-search-capabilities svg {
|
.v2-vehicle-query-panel .v2-vehicle-search-form > .v2-vehicle-search-picker {
|
||||||
grid-row: 1 / span 2;
|
min-height: 42px;
|
||||||
color: var(--v2-blue);
|
border: 1px solid #d7e1ed;
|
||||||
font-size: 18px;
|
border-radius: 9px;
|
||||||
|
background: #fff;
|
||||||
|
padding-inline: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v2-vehicle-search-capabilities b {
|
.v2-vehicle-query-panel .v2-vehicle-search-form > .semi-button {
|
||||||
grid-column: 2;
|
height: 42px;
|
||||||
overflow: hidden;
|
margin: 0;
|
||||||
color: #33475e;
|
|
||||||
font-size: 11px;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.v2-vehicle-search-capabilities small {
|
.v2-vehicle-query-panel .v2-vehicle-search-options.v2-vehicle-candidate-list {
|
||||||
grid-column: 2;
|
top: calc(100% + 8px);
|
||||||
overflow: hidden;
|
left: 10px;
|
||||||
color: #8794a5;
|
width: calc(100% - 20px);
|
||||||
font-size: 9px;
|
}
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
.v2-vehicle-recent-card.semi-card {
|
||||||
|
width: min(1280px, 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-vehicle-recent-grid {
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-vehicle-recent-item.semi-button {
|
||||||
|
min-height: 78px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1100px) {
|
||||||
|
.v2-vehicle-recent-grid {
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.v2-vehicle-record-page {
|
.v2-vehicle-record-page {
|
||||||
@@ -1553,32 +1578,42 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
.v2-vehicle-search-capabilities {
|
.v2-vehicle-search-page {
|
||||||
gap: 6px;
|
gap: 9px;
|
||||||
margin-top: 13px;
|
padding: 9px 8px 92px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v2-vehicle-search-capabilities > span {
|
.v2-vehicle-query-panel .v2-vehicle-search-form {
|
||||||
display: flex;
|
min-height: 0;
|
||||||
min-height: 44px;
|
border-top: 0;
|
||||||
justify-content: center;
|
padding: 9px;
|
||||||
gap: 6px;
|
|
||||||
padding: 7px 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.v2-vehicle-search-capabilities svg {
|
.v2-vehicle-query-panel .v2-vehicle-search-form.is-mobile-collapsed {
|
||||||
flex: 0 0 auto;
|
|
||||||
font-size: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v2-vehicle-search-capabilities b {
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v2-vehicle-search-capabilities small {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.v2-vehicle-query-panel .v2-vehicle-search-form > .v2-vehicle-search-picker {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 46px;
|
||||||
|
flex: 1 1 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-vehicle-query-panel .v2-vehicle-search-form > .semi-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 44px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-vehicle-query-panel .v2-vehicle-search-options.v2-vehicle-candidate-list {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v2-vehicle-recent-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
.v2-track-detail-sidesheet .semi-sidesheet-inner {
|
.v2-track-detail-sidesheet .semi-sidesheet-inner {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 18px 18px 0 0;
|
border-radius: 18px 18px 0 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user