feat: refine mobile track workspace
This commit is contained in:
@@ -276,6 +276,10 @@ test('uses a Semi bottom SideSheet for mobile track criteria and evidence', asyn
|
||||
expect(screen.queryByRole('textbox', { name: '搜索轨迹车辆' })).not.toBeInTheDocument();
|
||||
expect(screen.getByText('07-15 00:00 – 07-15 23:59 · 自动来源')).toBeInTheDocument();
|
||||
expect(screen.getByText('8 km · 1 个停留 · 3 个事件')).toBeInTheDocument();
|
||||
expect(sheet).toHaveStyle({ height: 'min(82dvh, 326px)' });
|
||||
fireEvent.click(screen.getByRole('tab', { name: /事件点/ }));
|
||||
await waitFor(() => expect(sheet).toHaveStyle({ height: 'min(82dvh, 450px)' }));
|
||||
fireEvent.click(screen.getByRole('tab', { name: /停留点/ }));
|
||||
fireEvent.click(screen.getByRole('button', { name: /停留 00:05:00/ }));
|
||||
expect(view.container.querySelector('.v2-track-page')).toHaveClass('is-rail-collapsed');
|
||||
fireEvent.click(screen.getByRole('button', { name: '打开轨迹详情' }));
|
||||
|
||||
@@ -39,6 +39,9 @@ const TRACK_SOURCE_OPTIONS = [
|
||||
const numberFormatters = new Map<number, Intl.NumberFormat>();
|
||||
const timeFormatter = new Intl.DateTimeFormat('zh-CN', { timeZone: 'Asia/Shanghai', hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
||||
const dateTimeFormatter = new Intl.DateTimeFormat('zh-CN', { timeZone: 'Asia/Shanghai', hour12: false, month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
||||
const TRACK_SHEET_MAX_HEIGHT_PX = 720;
|
||||
const TRACK_SHEET_CHROME_HEIGHT_PX = 264;
|
||||
const TRACK_SHEET_ROW_HEIGHT_PX = 62;
|
||||
|
||||
function number(value: number, digits = 1) {
|
||||
let formatter = numberFormatters.get(digits);
|
||||
@@ -116,6 +119,14 @@ function eventTone(type: string) {
|
||||
return 'info';
|
||||
}
|
||||
|
||||
function mobileTrackSheetHeight(track: TrackPlaybackResponse | undefined, queryCollapsed: boolean, tab: PanelTab) {
|
||||
if (!track || !queryCollapsed || tab === 'overview') return `min(82dvh, ${TRACK_SHEET_MAX_HEIGHT_PX}px)`;
|
||||
const itemCount = tab === 'stops' ? track.stops.length : track.events.length;
|
||||
const visibleRows = itemCount ? Math.min(itemCount, 7) : 2;
|
||||
const contentHeight = Math.min(TRACK_SHEET_MAX_HEIGHT_PX, TRACK_SHEET_CHROME_HEIGHT_PX + visibleRows * TRACK_SHEET_ROW_HEIGHT_PX);
|
||||
return `min(82dvh, ${contentHeight}px)`;
|
||||
}
|
||||
|
||||
function VehiclePicker({ value, onChange, onSelect }: { value: string; onChange: (value: string) => void; onSelect: (vehicle: VehicleRow) => void }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [debounced, setDebounced] = useState(value.trim());
|
||||
@@ -390,7 +401,7 @@ export default function TrackPage() {
|
||||
className="v2-track-detail-sidesheet"
|
||||
visible={!railCollapsed}
|
||||
placement="bottom"
|
||||
height="min(82dvh, 720px)"
|
||||
height={mobileTrackSheetHeight(track, queryCollapsed, panelTab)}
|
||||
aria-label="轨迹查询与明细"
|
||||
title={<div className="v2-track-detail-sheet-title"><strong>轨迹查询与明细</strong><span>{track ? `${number(track.summary.distanceKm)} km · ${track.stops.length} 个停留 · ${track.events.length} 个事件` : '选择车辆和时间范围'}</span></div>}
|
||||
footer={null}
|
||||
|
||||
@@ -3217,6 +3217,88 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 700px) and (max-height: 500px) and (orientation: landscape) {
|
||||
.v2-track-current-card.semi-card,
|
||||
.v2-track-page.is-rail-collapsed .v2-track-current-card.semi-card {
|
||||
top: 6px;
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: 8px;
|
||||
width: min(318px, 48vw);
|
||||
min-width: 0;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.v2-track-current-card .v2-workspace-panel-header {
|
||||
min-height: 42px;
|
||||
padding: 5px 8px;
|
||||
}
|
||||
|
||||
.v2-track-current-card .v2-workspace-panel-meta .semi-tag {
|
||||
min-width: 40px;
|
||||
padding-inline: 6px;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.v2-track-current-card > .semi-card-body > .v2-track-current-metrics > span {
|
||||
padding: 5px 6px;
|
||||
}
|
||||
|
||||
.v2-track-current-card > .semi-card-body > .v2-track-current-metrics small {
|
||||
font-size: 8px;
|
||||
}
|
||||
|
||||
.v2-track-current-card > .semi-card-body > .v2-track-current-metrics strong {
|
||||
margin-top: 2px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.v2-track-current-card > .semi-card-body > .v2-track-current-evidence {
|
||||
min-height: 32px;
|
||||
gap: 5px;
|
||||
padding: 4px 7px;
|
||||
}
|
||||
|
||||
.v2-track-current-evidence > em {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.v2-track-stage-tools {
|
||||
top: 6px;
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
.v2-track-page.is-mobile-layout .v2-track-playback-dock.semi-card,
|
||||
.v2-track-page.is-mobile-layout .v2-track-playback-dock > .semi-card-body {
|
||||
min-height: 88px;
|
||||
}
|
||||
|
||||
.v2-track-page.is-mobile-layout .v2-track-playback-dock > .semi-card-body {
|
||||
gap: 6px;
|
||||
padding: 6px 8px !important;
|
||||
}
|
||||
|
||||
.v2-track-page.is-mobile-layout .v2-track-progress-slider.semi-slider-wrapper {
|
||||
margin-block: 6px 2px;
|
||||
}
|
||||
|
||||
.v2-track-stage:has(.v2-track-current-card) .v2-track-rail-expand {
|
||||
top: 52px;
|
||||
right: 8px;
|
||||
bottom: auto;
|
||||
left: auto;
|
||||
min-width: 126px;
|
||||
min-height: 38px;
|
||||
padding: 5px 8px;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.v2-track-rail-expand.semi-button .semi-icon {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mileage workspace refinement: expose the active source strategy and keep the
|
||||
* mobile matrix dense without sacrificing the fixed plate/period columns. */
|
||||
.v2-mileage-source-trigger .semi-button-content {
|
||||
|
||||
Reference in New Issue
Block a user