refactor: polish semi mileage workspace

This commit is contained in:
lingniu
2026-07-19 14:19:43 +08:00
parent 4da26ad3ba
commit 2d987fd185
3 changed files with 245 additions and 49 deletions

View File

@@ -2,7 +2,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { afterEach, expect, test, vi } from 'vitest';
import { MemoryRouter } from 'react-router-dom';
import StatisticsPage from './StatisticsPage';
import StatisticsPage, { mileageRangeContainsDate } from './StatisticsPage';
import { buildMonitorPath, withMonitorReturn } from '../routing/monitorContext';
import { ROUTER_FUTURE } from '../routing/routerConfig';
@@ -37,6 +37,13 @@ function prepareData() {
mocks.vehicleCoverage.mockResolvedValue({ items: [{ vin: 'LTEST000000000001', plate: '粤A12345' }], total: 1, limit: 20, offset: 0 });
}
test('refreshes only ranges that include the current business date', () => {
expect(mileageRangeContainsDate({ dateFrom: '2026-07-13', dateTo: '2026-07-19' }, '2026-07-19')).toBe(true);
expect(mileageRangeContainsDate({ dateFrom: '2026-07-19', dateTo: '2026-07-19' }, '2026-07-19')).toBe(true);
expect(mileageRangeContainsDate({ dateFrom: '2026-07-13', dateTo: '2026-07-18' }, '2026-07-19')).toBe(false);
expect(mileageRangeContainsDate({ dateFrom: '2026-07-20', dateTo: '2026-07-20' }, '2026-07-19')).toBe(false);
});
test('renders only the desktop matrix with dates as columns and a period total', async () => {
prepareData();
const view = renderPage('/statistics?vins=LTEST000000000001&dateFrom=2026-07-13&dateTo=2026-07-14');
@@ -53,6 +60,10 @@ test('renders only the desktop matrix with dates as columns and a period total',
expect(screen.getByLabelText('里程查询工作区')).toHaveTextContent('GB32960 优先');
expect(screen.getByRole('heading', { name: '里程范围', level: 5 })).toBeInTheDocument();
expect(screen.getByText('车牌、自然日与里程数据源策略')).toBeInTheDocument();
expect(view.container.querySelector('.v2-mileage-date-range.semi-datepicker')).toBeInTheDocument();
expect(screen.getByRole('group', { name: '快捷日期范围' })).toHaveClass('semi-button-group');
expect(screen.getByPlaceholderText('开始日期')).toHaveValue('2026-07-13');
expect(screen.getByPlaceholderText('结束日期')).toHaveValue('2026-07-14');
expect(screen.getAllByText('1 辆 · 2 天').some((element) => element.closest('.semi-tag'))).toBe(true);
expect(screen.queryByText('当日起始里程')).not.toBeInTheDocument();
expect(screen.queryByText('数据来源')).not.toBeInTheDocument();

View File

@@ -1,5 +1,5 @@
import { IconArrowDown, IconArrowUp, IconClose, IconDownload, IconInfoCircle, IconRefresh, IconSearch, IconSetting } from '@douyinfe/semi-icons';
import { Button, Card, Empty, Input, Spin, Switch, Table, Tag } from '@douyinfe/semi-ui';
import { Button, ButtonGroup, Card, DatePicker, Empty, Input, Progress, Spin, Switch, Table, Tag } from '@douyinfe/semi-ui';
import { useQuery } from '@tanstack/react-query';
import { type CSSProperties, FormEvent, type KeyboardEvent, memo, type RefObject, useEffect, useMemo, useRef, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
@@ -30,6 +30,7 @@ const PAGE_SIZE = 20;
const EXPORT_VEHICLE_PAGE_SIZE = 2_000;
const EXPORT_VIN_BATCH_SIZE = 50;
const MAX_MILEAGE_RANGE_DAYS = 366;
const CURRENT_DAY_REFRESH_MS = 60_000;
type VehicleOption = Pick<VehicleRow, 'vin' | 'plate'>;
type MileageProtocol = 'GB32960' | 'JT808' | 'YUTONG_MQTT';
@@ -58,6 +59,13 @@ function isSameRange(criteria: Pick<Criteria, 'dateFrom' | 'dateTo'>, range: { d
return criteria.dateFrom === range.dateFrom && criteria.dateTo === range.dateTo;
}
export function mileageRangeContainsDate(
range: { dateFrom: string; dateTo: string },
date = localDate()
) {
return Boolean(range.dateFrom && range.dateTo && range.dateFrom <= date && range.dateTo >= date);
}
function formatKm(value?: number) {
if (value == null || !Number.isFinite(value)) return '—';
return formatZhNumber(value, 1);
@@ -77,6 +85,20 @@ function mileageDateRangeError(criteria: Pick<Criteria, 'dateFrom' | 'dateTo'>)
return '';
}
function datePickerRange(dateValue?: Date | Date[] | string | string[], formattedValue?: string | string[] | Date | Date[]) {
const values = Array.isArray(formattedValue) && formattedValue.length === 2
? formattedValue
: Array.isArray(dateValue) && dateValue.length === 2 ? dateValue : [];
if (values.length !== 2) return;
const normalized = values.map((value) => {
if (value instanceof Date) return localDate(value);
if (typeof value === 'number') return localDate(new Date(value));
return String(value).slice(0, 10);
});
if (normalized.some((value) => !/^\d{4}-\d{2}-\d{2}$/.test(value))) return;
return { dateFrom: normalized[0], dateTo: normalized[1] };
}
function mileageParams(criteria: Criteria, offset = 0) {
const params = new URLSearchParams({ dateFrom: criteria.dateFrom, dateTo: criteria.dateTo });
if (criteria.vehicles.length) params.set('vins', criteria.vehicles.map((vehicle) => vehicle.vin).join(','));
@@ -441,8 +463,27 @@ export default function StatisticsPage() {
const statisticsScope = statisticsParams.toString();
const rowsCriteria = useMemo(() => ({ ...criteria, vehicles: displayVehicles }), [criteria, displayVehicles]);
const rowsParams = useMemo(() => mileageParams(rowsCriteria, 0), [rowsCriteria]);
const statistics = useQuery({ queryKey: ['mileage-statistics', statisticsScope], queryFn: ({ signal }) => api.mileageStatistics(statisticsParams, signal), enabled: !criteriaError, staleTime: 60_000, gcTime: QUERY_MEMORY.summaryGcTime });
const mileage = useQuery<Page<DailyMileageRow>>({ queryKey: ['daily-mileage-query', statisticsScope, rowsParams.toString()], queryFn: ({ signal }) => api.dailyMileage(rowsParams, signal), enabled: !criteriaError && displayVehicles.length > 0, staleTime: 60_000, gcTime: QUERY_MEMORY.highVolumeGcTime, placeholderData: retainPreviousPageWithinScope<Page<DailyMileageRow>>(statisticsScope, 2) });
const currentDayRange = !criteriaError && mileageRangeContainsDate(criteria);
const currentDayRefreshInterval = currentDayRange ? CURRENT_DAY_REFRESH_MS : false;
const statistics = useQuery({
queryKey: ['mileage-statistics', statisticsScope],
queryFn: ({ signal }) => api.mileageStatistics(statisticsParams, signal),
enabled: !criteriaError,
staleTime: CURRENT_DAY_REFRESH_MS,
gcTime: QUERY_MEMORY.summaryGcTime,
refetchInterval: currentDayRefreshInterval,
refetchIntervalInBackground: false
});
const mileage = useQuery<Page<DailyMileageRow>>({
queryKey: ['daily-mileage-query', statisticsScope, rowsParams.toString()],
queryFn: ({ signal }) => api.dailyMileage(rowsParams, signal),
enabled: !criteriaError && displayVehicles.length > 0,
staleTime: CURRENT_DAY_REFRESH_MS,
gcTime: QUERY_MEMORY.highVolumeGcTime,
placeholderData: retainPreviousPageWithinScope<Page<DailyMileageRow>>(statisticsScope, 2),
refetchInterval: currentDayRefreshInterval,
refetchIntervalInBackground: false
});
const dates = useMemo(() => criteriaError ? [] : rangeDates(criteria.dateFrom, criteria.dateTo), [criteria.dateFrom, criteria.dateTo, criteriaError]);
const mileageByVin = useMemo(() => {
const index = new Map<string, { plate: string; days: Map<string, number>; sources: Map<string, string> }>();
@@ -592,11 +633,27 @@ export default function StatisticsPage() {
const rangeSummary = criteria.vehicles.length ? `已选 ${criteria.vehicles.length} 辆 · ${inclusiveDays(criteria.dateFrom, criteria.dateTo)}` : `全部车辆 · ${inclusiveDays(criteria.dateFrom, criteria.dateTo)}`;
const filterForm = <form className="v2-mileage-filter" onSubmit={submit}>
<VehicleMultiSelect value={draft.vehicles} onChange={(vehicles) => setDraft((current) => ({ ...current, vehicles }))} />
<label><span></span><Input aria-label="开始日期" type="date" value={draft.dateFrom} max={draft.dateTo} onChange={(value) => setDraft((current) => ({ ...current, dateFrom: value }))} /></label>
<label><span></span><Input aria-label="结束日期" type="date" value={draft.dateTo} min={draft.dateFrom} onChange={(value) => setDraft((current) => ({ ...current, dateTo: value }))} /></label>
<label className="v2-mileage-date-field">
<span id="v2-mileage-date-range-label"></span>
<DatePicker
className="v2-mileage-date-range"
type="dateRange"
density="compact"
format="yyyy-MM-dd"
value={[draft.dateFrom, draft.dateTo]}
placeholder={['开始日期', '结束日期']}
showClear={false}
onChangeWithDateFirst
aria-labelledby="v2-mileage-date-range-label"
onChange={(value, formattedValue) => {
const range = datePickerRange(value, formattedValue);
if (range) setDraft((current) => ({ ...current, ...range }));
}}
/>
</label>
<Button className="v2-primary-button v2-mileage-inline-submit" theme="solid" htmlType="submit"></Button>
<SourceStrategy value={draft.sources} onChange={(sources) => setDraft((current) => ({ ...current, sources }))} />
<div className="v2-mileage-ranges"><span></span><Button theme={isSameRange(draft, todayRange) ? 'solid' : 'light'} onClick={() => setRange(todayRange)}></Button><Button theme={isSameRange(draft, yesterdayRange) ? 'solid' : 'light'} onClick={() => setRange(yesterdayRange)}></Button><Button theme={isSameRange(draft, sevenDayRange) ? 'solid' : 'light'} onClick={() => setRange(sevenDayRange)}> 7 </Button><Button theme={isSameRange(draft, thirtyDayRange) ? 'solid' : 'light'} onClick={() => setRange(thirtyDayRange)}> 30 </Button><Button theme={isSameRange(draft, ninetyDayRange) ? 'solid' : 'light'} onClick={() => setRange(ninetyDayRange)}> 90 </Button></div>
<div className="v2-mileage-ranges"><span></span><ButtonGroup aria-label="快捷日期范围"><Button theme={isSameRange(draft, todayRange) ? 'solid' : 'light'} onClick={() => setRange(todayRange)}></Button><Button theme={isSameRange(draft, yesterdayRange) ? 'solid' : 'light'} onClick={() => setRange(yesterdayRange)}></Button><Button theme={isSameRange(draft, sevenDayRange) ? 'solid' : 'light'} onClick={() => setRange(sevenDayRange)}> 7 </Button><Button theme={isSameRange(draft, thirtyDayRange) ? 'solid' : 'light'} onClick={() => setRange(thirtyDayRange)}> 30 </Button><Button theme={isSameRange(draft, ninetyDayRange) ? 'solid' : 'light'} onClick={() => setRange(ninetyDayRange)}> 90 </Button></ButtonGroup></div>
</form>;
const filterValidation = validationError || criteriaError ? <p className="v2-mileage-validation" role="alert">{validationError || criteriaError}</p> : null;
@@ -668,7 +725,9 @@ export default function StatisticsPage() {
/>
{exportProgress ? <div className="v2-mileage-export-progress" role="progressbar" aria-label={exportProgress.label} aria-valuemin={0} aria-valuemax={100} aria-valuenow={exportPercent}>
<span><strong>{exportProgress.label}</strong><small>{exportPercent == null ? '处理中' : `${exportPercent}%`}</small></span>
<i className={exportPercent == null ? 'is-indeterminate' : ''}><b style={exportPercent == null ? undefined : { width: `${exportPercent}%` }} /></i>
{exportPercent == null
? <Spin className="v2-mileage-export-spinner" size="small" />
: <Progress className="v2-mileage-export-bar" percent={exportPercent} showInfo={false} size="small" strokeLinecap="round" aria-label={`${exportProgress.label} ${exportPercent}%`} />}
</div> : null}
{!resultsLoading && displayVehicles.length ? <MileageMatrixGuide /> : null}
{resultsLoading ? <PanelLoading className="v2-mileage-loading" title="正在查询里程" description="新筛选范围返回前不会展示上一范围的数据。" /> : displayVehicles.length ? <MileageTable rows={matrixRows} dates={dates} scrollRef={tableScrollRef} /> : null}

View File

@@ -14,7 +14,7 @@
justify-content: space-between;
gap: 16px;
border-bottom: 1px solid var(--v2-border);
background: linear-gradient(180deg, #fff 0%, #fbfcfe 100%);
background: #fff;
padding: 8px 14px;
}
@@ -6978,7 +6978,7 @@
gap: 9px;
border-bottom: 1px solid #e6ebf2;
border-radius: 12px 12px 0 0;
background: linear-gradient(100deg, #f8fbff 0%, #f5f8fc 58%, #fbfcfe 100%);
background: #f8fafc;
padding: 7px 12px;
}
@@ -9982,7 +9982,7 @@
display: flex;
width: 100%;
max-width: 1480px;
min-height: 52px;
min-height: 48px;
flex: 0 0 auto;
align-items: center;
justify-content: space-between;
@@ -9992,7 +9992,7 @@
border-radius: 10px;
background: #fff;
padding: 7px 9px 7px 14px;
box-shadow: 0 6px 20px rgba(31, 50, 76, .035);
box-shadow: 0 4px 14px rgba(31, 50, 76, .03);
}
.v2-workspace-command-copy {
@@ -10642,8 +10642,8 @@
/* Final cascade layer for the shared command hierarchy. */
.v2-workspace-command-bar {
box-sizing: border-box;
height: 52px;
min-height: 52px;
height: 48px;
min-height: 48px;
padding-block: 5px;
}
@@ -14541,8 +14541,8 @@
* operations workspaces.
*/
.v2-mileage-page {
gap: 10px;
padding: 14px 18px 16px;
gap: 8px;
padding: 12px 16px 14px;
}
.v2-mileage-discovery-shell {
@@ -14552,9 +14552,9 @@
gap: 0;
overflow: visible;
border: 1px solid #d8e3ef;
border-radius: 14px;
border-radius: 12px;
background: #fff;
box-shadow: 0 9px 28px rgba(31, 53, 80, .055);
box-shadow: 0 7px 22px rgba(31, 53, 80, .045);
}
.v2-mileage-discovery-shell > .v2-mileage-command-bar {
@@ -14564,7 +14564,7 @@
min-height: 46px;
border: 0;
border-bottom: 1px solid #e3eaf2;
border-radius: 14px 14px 0 0;
border-radius: 12px 12px 0 0;
padding-inline: 13px 10px;
box-shadow: none;
}
@@ -14579,7 +14579,7 @@
width: 100%;
overflow: visible;
border: 0;
border-radius: 0 0 14px 14px;
border-radius: 0 0 12px 12px;
box-shadow: none;
}
@@ -14590,23 +14590,67 @@
.v2-mileage-query-panel .v2-workspace-filter-heading {
min-height: 44px;
border-bottom-color: #e3eaf2;
background: linear-gradient(100deg, #f7faff 0%, #f9fbfd 58%, #fff 100%);
background: #f8fafc;
padding-inline: 13px;
}
.v2-mileage-query-panel .v2-mileage-filter {
gap: 10px;
grid-template-columns: minmax(220px, 1.15fr) minmax(224px, .95fr) auto auto minmax(228px, auto);
align-items: end;
gap: 8px;
background: #fff;
padding: 11px 12px 12px;
padding: 8px 10px;
}
.v2-mileage-filter > label {
gap: 5px;
gap: 4px;
color: #607187;
font-size: 12px;
font-size: 11px;
font-weight: 650;
}
.v2-mileage-filter > label > span:first-child {
min-height: 14px;
font-size: 10px;
line-height: 14px;
}
.v2-mileage-query-panel .v2-mileage-vehicle-field > small {
display: none;
}
.v2-mileage-date-range.semi-datepicker {
width: 100%;
min-height: 38px;
}
.v2-mileage-date-range .semi-datepicker-input {
width: 100%;
}
.v2-mileage-date-range .semi-input-wrapper {
min-height: 38px;
border-color: #d8e2ed;
border-radius: 8px;
background: #fbfcfe;
}
.v2-mileage-date-range .semi-input-wrapper:hover {
border-color: #b9c9dc;
background: #fff;
}
.v2-mileage-date-range .semi-input-wrapper-focus {
border-color: #75a5ed;
background: #fff;
box-shadow: 0 0 0 3px rgba(37, 99, 235, .09);
}
.v2-mileage-date-range .semi-input {
font-size: 12px;
font-variant-numeric: tabular-nums;
}
.v2-mileage-multiselect,
.v2-mileage-filter > label > .semi-input-wrapper {
min-height: 38px;
@@ -14644,6 +14688,11 @@
box-shadow: 0 4px 12px rgba(18, 104, 223, .16);
}
.v2-mileage-inline-submit.semi-button,
.v2-mileage-source-strategy {
margin-top: 0;
}
.v2-mileage-source-trigger.semi-button {
min-height: 38px;
border-color: #d8e3ef;
@@ -14674,6 +14723,12 @@
padding: 3px;
}
.v2-mileage-ranges > .semi-button-group {
display: flex;
min-width: 0;
gap: 2px;
}
.v2-mileage-ranges .semi-button {
min-height: 30px;
border-radius: 6px;
@@ -14741,9 +14796,9 @@
}
.v2-mileage-results > .semi-card-body > .v2-workspace-panel-header {
min-height: 50px;
min-height: 46px;
border-bottom-color: #e2e9f1;
background: linear-gradient(90deg, #fff 0%, #fbfcfe 100%);
background: #fff;
padding-inline: 14px;
}
@@ -14772,7 +14827,7 @@
align-items: center;
gap: 14px;
border-bottom: 1px solid #e2e9f1;
background: linear-gradient(90deg, #f9fbfe 0%, #fff 100%);
background: #f8fafc;
padding: 5px 14px;
color: #6c7d92;
font-size: 11px;
@@ -14897,11 +14952,25 @@
}
.v2-mileage-results > .semi-card-body > footer {
min-height: 40px;
min-height: 36px;
border-top-color: #e3eaf2;
background: #fbfcfe;
}
.v2-mileage-export-progress {
min-height: 40px;
padding: 7px 14px;
}
.v2-mileage-export-progress > .v2-mileage-export-bar {
min-width: 160px;
flex: 1 1 auto;
}
.v2-mileage-export-progress > .v2-mileage-export-spinner {
margin-left: auto;
}
.v2-mileage-evidence {
min-height: 20px;
align-items: center;
@@ -14936,11 +15005,31 @@
@media (min-width: 681px) and (max-width: 1050px) {
.v2-mileage-query-panel .v2-mileage-filter {
grid-template-columns: minmax(200px, 1.25fr) minmax(220px, 1fr) auto;
grid-template-areas:
"vehicle date submit"
"source ranges ranges";
row-gap: 10px;
}
.v2-mileage-summary > .semi-card-body {
grid-template-columns: minmax(285px, 1fr) minmax(0, 2fr);
.v2-mileage-query-panel .v2-mileage-vehicle-field {
grid-area: vehicle;
}
.v2-mileage-query-panel .v2-mileage-date-field {
grid-area: date;
}
.v2-mileage-query-panel .v2-mileage-filter > .v2-primary-button {
grid-area: submit;
}
.v2-mileage-query-panel .v2-mileage-source-strategy {
grid-area: source;
}
.v2-mileage-query-panel .v2-mileage-ranges {
grid-area: ranges;
}
}
@@ -14970,6 +15059,7 @@
}
.v2-mileage-filter > label > .semi-input-wrapper,
.v2-mileage-date-range .semi-input-wrapper,
.v2-mileage-multiselect,
.v2-mileage-source-trigger.semi-button,
.v2-mileage-filter > .v2-primary-button.semi-button {
@@ -14981,6 +15071,30 @@
border-radius: 10px;
}
.v2-mileage-query-panel .v2-mileage-vehicle-field > small {
display: block;
}
.v2-mileage-date-range.semi-datepicker,
.v2-mileage-date-range .semi-datepicker-input,
.v2-mileage-date-range .semi-input-wrapper {
width: 100%;
}
.v2-mileage-ranges > .semi-button-group {
width: 100%;
overflow-x: auto;
scrollbar-width: none;
}
.v2-mileage-ranges > .semi-button-group::-webkit-scrollbar {
display: none;
}
.v2-mileage-ranges > .semi-button-group > .semi-button {
flex: 1 0 auto;
}
.v2-mileage-summary-secondary .v2-mileage-summary-card strong {
font-size: 16px;
}
@@ -15645,7 +15759,7 @@
.v2-workspace-metric-rail.is-queue > .semi-card-body {
display: grid;
min-height: 58px;
min-height: 54px;
grid-template-columns: minmax(0, 1fr);
}
@@ -15662,9 +15776,9 @@
.v2-workspace-metric-list > span {
display: grid;
min-width: 0;
min-height: 58px;
min-height: 54px;
grid-template-columns: auto minmax(0, 1fr);
grid-template-rows: auto auto;
grid-template-rows: 14px 24px;
align-content: center;
column-gap: 10px;
padding: 7px 13px;
@@ -15681,7 +15795,7 @@
.v2-workspace-metric-action.semi-button {
width: 100%;
height: 100%;
min-height: 58px;
min-height: 54px;
border-radius: 0;
padding: 0;
color: inherit;
@@ -15700,9 +15814,9 @@
display: grid;
width: 100%;
min-width: 0;
min-height: 58px;
min-height: 54px;
grid-template-columns: auto minmax(0, 1fr);
grid-template-rows: auto auto;
grid-template-rows: 14px 24px;
align-content: center;
column-gap: 10px;
padding: 7px 13px;
@@ -15717,6 +15831,7 @@
font-weight: 650;
line-height: 14px;
white-space: nowrap;
margin: 0;
}
.v2-workspace-metric-list > span > strong,
@@ -15727,6 +15842,7 @@
font-variant-numeric: tabular-nums;
line-height: 24px;
white-space: nowrap;
margin: 0;
}
.v2-workspace-metric-list > span > em,
@@ -15741,6 +15857,7 @@
line-height: 14px;
text-overflow: ellipsis;
white-space: nowrap;
margin: 0;
}
.v2-workspace-metric-list > span.is-secondary > strong,
@@ -15749,8 +15866,8 @@
}
.v2-workspace-metric-list > span.is-primary {
background: linear-gradient(145deg, #edf5ff 0%, #f8fbff 100%);
box-shadow: inset 0 -3px #1f6feb;
background: #f5f9ff;
box-shadow: inset 3px 0 #3b82f6;
}
.v2-workspace-metric-list > span.is-primary > :is(small, strong),
@@ -15759,8 +15876,8 @@
}
.v2-workspace-metric-list > span.is-danger {
background: linear-gradient(145deg, #fff 0%, #fff8f7 100%);
box-shadow: inset 0 -3px #e2554f;
background: #fff8f7;
box-shadow: inset 3px 0 #e2554f;
}
.v2-workspace-metric-list > span.is-danger > :is(small, strong),
@@ -15784,21 +15901,21 @@
}
.v2-workspace-metric-list > span.is-action.is-danger {
background: linear-gradient(145deg, #fff 0%, #fff8f7 100%);
background: #fff8f7;
}
.v2-workspace-metric-list > span.is-action.is-warning {
background: linear-gradient(145deg, #fff 0%, #fffcf5 100%);
background: #fffcf5;
}
.v2-workspace-metric-list > span.is-action.is-active {
background: linear-gradient(145deg, #edf5ff 0%, #f8fbff 100%);
box-shadow: inset 0 -3px #1f6feb;
background: #f5f9ff;
box-shadow: inset 3px 0 #3b82f6;
}
.v2-workspace-metric-list > span.is-action.is-active.is-danger {
background: linear-gradient(145deg, #fff1ef 0%, #fff8f7 100%);
box-shadow: inset 0 -3px #e2554f;
background: #fff4f2;
box-shadow: inset 3px 0 #e2554f;
}
.v2-workspace-metric-context {
@@ -23245,7 +23362,7 @@
.v2-mileage-summary.v2-workspace-metric-rail.is-queue > .semi-card-body {
display: grid;
height: auto;
min-height: 58px;
min-height: 54px;
grid-template-columns: minmax(0, 1fr);
gap: 0;
}
@@ -23256,7 +23373,12 @@
.v2-mileage-summary .v2-workspace-metric-list > span {
display: grid;
min-height: 58px;
min-height: 54px;
}
.v2-mileage-summary .v2-workspace-metric-list > span > :is(small, strong, em),
.v2-mileage-summary .v2-workspace-metric-action .semi-button-content > :is(small, strong, em) {
margin: 0;
}
.v2-mileage-summary-unit {
@@ -23290,6 +23412,10 @@
.v2-mileage-summary .v2-workspace-metric-list > span {
min-height: 56px;
}
.v2-mileage-summary .v2-workspace-metric-list > span.is-secondary {
display: none;
}
}
/*