From 40c210a192a0aa501cb76ec67fd07ae2d9a69d4d Mon Sep 17 00:00:00 2001 From: lingniu Date: Sun, 19 Jul 2026 16:25:48 +0800 Subject: [PATCH] refactor(ui): polish semi mileage discovery --- .../web/src/v2/pages/StatisticsPage.test.tsx | 6 +- .../apps/web/src/v2/pages/StatisticsPage.tsx | 51 ++++++++++++++- .../apps/web/src/v2/styles/workspace.css | 65 ++++++++++++++++++- 3 files changed, 116 insertions(+), 6 deletions(-) diff --git a/vehicle-data-platform/apps/web/src/v2/pages/StatisticsPage.test.tsx b/vehicle-data-platform/apps/web/src/v2/pages/StatisticsPage.test.tsx index ec6e5b15..65db6d6d 100644 --- a/vehicle-data-platform/apps/web/src/v2/pages/StatisticsPage.test.tsx +++ b/vehicle-data-platform/apps/web/src/v2/pages/StatisticsPage.test.tsx @@ -122,6 +122,8 @@ test('defaults to seven days and supports today and yesterday shortcuts', async await waitFor(() => expect(mocks.mileageStatistics).toHaveBeenCalled()); expect(mocks.mileageStatistics.mock.calls[0][0].get('dateFrom')).toBe(sevenDaysAgo); expect(mocks.mileageStatistics.mock.calls[0][0].get('dateTo')).toBe(today); + expect(screen.getByRole('button', { name: '近 7 天' })).toHaveAttribute('aria-pressed', 'true'); + expect(screen.getByRole('button', { name: '今天' })).toHaveAttribute('aria-pressed', 'false'); fireEvent.click(screen.getByRole('button', { name: '昨天' })); await waitFor(() => { @@ -129,6 +131,7 @@ test('defaults to seven days and supports today and yesterday shortcuts', async expect(params.get('dateFrom')).toBe(yesterday); expect(params.get('dateTo')).toBe(yesterday); }); + expect(screen.getByRole('button', { name: '昨天' })).toHaveAttribute('aria-pressed', 'true'); fireEvent.click(screen.getByRole('button', { name: '今天' })); await waitFor(() => { @@ -136,6 +139,7 @@ test('defaults to seven days and supports today and yesterday shortcuts', async expect(params.get('dateFrom')).toBe(today); expect(params.get('dateTo')).toBe(today); }); + expect(screen.getByRole('button', { name: '今天' })).toHaveAttribute('aria-pressed', 'true'); }); test('preserves the exact monitor return after a mileage date shortcut', async () => { @@ -280,7 +284,7 @@ test('lets users disable mileage sources and persists the source priority', asyn expect(screen.getByText('GPS 里程')).toBeInTheDocument(); expect(screen.getByText('GPS 里程').closest('.semi-tag')).toBeInTheDocument(); expect(screen.getAllByText('仪表盘里程')).toHaveLength(3); - expect(screen.getByRole('button', { name: /数据源.*GB32960 优先.*3\/3/ })).toHaveAttribute('title', '当前优先:国标 GB32960'); + expect(screen.getByRole('button', { name: /数据源策略.*GB32960 优先.*3\/3/ })).toHaveAttribute('title', '当前优先:国标 GB32960'); fireEvent.click(screen.getByRole('switch', { name: '禁用 国标 GB32960' })); fireEvent.click(screen.getByRole('button', { name: '上移 宇通 MQTT' })); fireEvent.click(screen.getByRole('button', { name: '查询' })); diff --git a/vehicle-data-platform/apps/web/src/v2/pages/StatisticsPage.tsx b/vehicle-data-platform/apps/web/src/v2/pages/StatisticsPage.tsx index d5597c91..b56b03a2 100644 --- a/vehicle-data-platform/apps/web/src/v2/pages/StatisticsPage.tsx +++ b/vehicle-data-platform/apps/web/src/v2/pages/StatisticsPage.tsx @@ -59,6 +59,34 @@ function isSameRange(criteria: Pick, range: { d return criteria.dateFrom === range.dateFrom && criteria.dateTo === range.dateTo; } +function MileageRangeShortcuts({ + value, + ranges, + onChange +}: { + value: Pick; + ranges: Array<{ label: string; range: { dateFrom: string; dateTo: string } }>; + onChange: (range: { dateFrom: string; dateTo: string }) => void; +}) { + return
+ 快捷日期 + + {ranges.map(({ label, range }) => { + const active = isSameRange(value, range); + return ; + })} + +
; +} + export function mileageRangeContainsDate( range: { dateFrom: string; dateTo: string }, date = localDate() @@ -160,8 +188,18 @@ function SourceStrategy({ value, onChange }: { value: MileageSourceOption[]; onC }; return
- setDraft((current) => ({ ...current, sources }))} /> -
快捷范围
+ ; const filterValidation = validationError || criteriaError ?

{validationError || criteriaError}

: null; diff --git a/vehicle-data-platform/apps/web/src/v2/styles/workspace.css b/vehicle-data-platform/apps/web/src/v2/styles/workspace.css index b3f34f79..84508b95 100644 --- a/vehicle-data-platform/apps/web/src/v2/styles/workspace.css +++ b/vehicle-data-platform/apps/web/src/v2/styles/workspace.css @@ -14551,6 +14551,8 @@ flex: 0 0 auto; gap: 0; overflow: visible; + container-name: mileage-discovery; + container-type: inline-size; border: 1px solid #d8e3ef; border-radius: 12px; background: #fff; @@ -14702,6 +14704,27 @@ font-size: 12px; } +.v2-mileage-source-trigger.semi-button .semi-button-content { + display: flex; + width: 100%; + min-width: 0; + flex: 1 1 auto; + align-items: center; + gap: 6px; +} + +.v2-mileage-source-trigger.semi-button .semi-button-content > span, +.v2-mileage-source-trigger.semi-button .semi-button-content > em { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.v2-mileage-source-trigger.semi-button .semi-button-content > b { + flex: 0 0 auto; + margin-left: auto; +} + .v2-mileage-source-trigger.semi-button:hover, .v2-mileage-source-trigger.semi-button[aria-expanded="true"] { border-color: #aec6e4; @@ -14715,7 +14738,10 @@ } .v2-mileage-ranges { + display: flex; min-height: 38px; + min-width: 0; + align-items: center; gap: 2px; border: 1px solid #e2e8f0; border-radius: 9px; @@ -14723,14 +14749,22 @@ padding: 3px; } +.v2-mileage-ranges > span { + flex: 0 0 auto; +} + .v2-mileage-ranges > .semi-button-group { display: flex; + width: 100%; min-width: 0; + flex: 1 1 auto; gap: 2px; } .v2-mileage-ranges .semi-button { min-height: 30px; + min-width: 52px; + flex: 1 1 0; border-radius: 6px; font-size: 11px; font-weight: 650; @@ -15003,9 +15037,9 @@ transform: translateY(-50%); } -@media (min-width: 681px) and (max-width: 1050px) { +@container mileage-discovery (min-width: 681px) and (max-width: 1100px) { .v2-mileage-query-panel .v2-mileage-filter { - grid-template-columns: minmax(200px, 1.25fr) minmax(220px, 1fr) auto; + grid-template-columns: minmax(260px, 1.25fr) minmax(242px, .95fr) auto; grid-template-areas: "vehicle date submit" "source ranges ranges"; @@ -15028,8 +15062,35 @@ grid-area: source; } + .v2-mileage-query-panel .v2-mileage-source-trigger.semi-button { + width: 100%; + min-width: 190px; + justify-content: flex-start; + } + .v2-mileage-query-panel .v2-mileage-ranges { + display: flex; grid-area: ranges; + width: 100%; + min-width: 0; + align-items: center; + justify-self: stretch; + } + + .v2-mileage-query-panel .v2-mileage-ranges > span { + display: inline-flex; + flex: 0 0 auto; + align-items: center; + padding-inline: 7px 5px; + color: #718196; + font-size: 10px; + font-weight: 650; + white-space: nowrap; + } + + .v2-mileage-query-panel .v2-mileage-ranges .semi-button { + min-width: 52px; + flex: 1 1 0; } }