refine Semi UI mileage workspace
This commit is contained in:
@@ -48,9 +48,12 @@ test('renders only the desktop matrix with dates as columns and a period total',
|
||||
expect(screen.getAllByText('7/13').length).toBeGreaterThan(0);
|
||||
expect(screen.getAllByText('7/14').length).toBeGreaterThan(0);
|
||||
expect(screen.getAllByText('粤A12345').length).toBeGreaterThan(0);
|
||||
expect(screen.getByLabelText('里程查询工作区')).toHaveClass('v2-workspace-command-bar', 'v2-mileage-command-bar');
|
||||
expect(screen.getByRole('heading', { name: '车辆里程分析', level: 5 })).toBeInTheDocument();
|
||||
expect(screen.getByLabelText('里程查询工作区')).toHaveTextContent('GB32960 优先');
|
||||
expect(screen.getByRole('heading', { name: '里程范围', level: 5 })).toBeInTheDocument();
|
||||
expect(screen.getByText('车牌、自然日与里程数据源策略')).toBeInTheDocument();
|
||||
expect(screen.getByText('1 辆 · 2 天').closest('.semi-tag')).toBeInTheDocument();
|
||||
expect(screen.getAllByText('1 辆 · 2 天').some((element) => element.closest('.semi-tag'))).toBe(true);
|
||||
expect(screen.queryByText('当日起始里程')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('数据来源')).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('img', { name: '每日行驶里程趋势图' })).not.toBeInTheDocument();
|
||||
@@ -60,6 +63,7 @@ test('renders only the desktop matrix with dates as columns and a period total',
|
||||
expect(screen.getByText('已绑定主车辆').closest('.semi-card')).toHaveClass('v2-mileage-summary-card');
|
||||
expect(screen.getByText('车辆每日里程').closest('.semi-card')).toHaveClass('v2-mileage-results');
|
||||
expect(view.container.querySelector('.v2-mileage-query-panel.semi-card')).toBeInTheDocument();
|
||||
expect(view.container.querySelector('.v2-mileage-discovery-shell > .v2-mileage-command-bar')).toBeInTheDocument();
|
||||
expect(view.container.querySelector('.v2-mileage-page > .v2-page-heading')).not.toBeInTheDocument();
|
||||
expect(view.container.querySelector('.v2-mileage-summary.semi-card')).toHaveAttribute('aria-label', '里程查询统计信息');
|
||||
expect(view.container.querySelector('.v2-mileage-summary-secondary.semi-card-group')).toBeInTheDocument();
|
||||
|
||||
@@ -13,6 +13,7 @@ import { TablePagination } from '../shared/TablePagination';
|
||||
import { VehicleCandidateList } from '../shared/VehicleCandidateList';
|
||||
import { mergeVehicleCandidates } from '../shared/vehicleCandidates';
|
||||
import { WorkspaceFilterPanel } from '../shared/WorkspaceFilterPanel';
|
||||
import { WorkspaceCommandBar } from '../shared/WorkspaceCommandBar';
|
||||
import { WorkspaceMetricRail } from '../shared/WorkspaceMetricRail';
|
||||
import { WorkspacePanelHeader } from '../shared/WorkspacePanelHeader';
|
||||
import { QUERY_MEMORY, retainPreviousPageWithinScope } from '../queryPolicy';
|
||||
@@ -534,28 +535,39 @@ export default function StatisticsPage() {
|
||||
|
||||
return <div className="v2-mileage-page" ref={pageRef}>
|
||||
<MonitorReturnBar />
|
||||
<WorkspaceFilterPanel
|
||||
className="v2-mileage-query-panel"
|
||||
title="里程范围"
|
||||
description="车牌、自然日与里程数据源策略"
|
||||
mobileSummary={criteria.vehicles.length ? `已选 ${criteria.vehicles.length} 辆 · ${inclusiveDays(criteria.dateFrom, criteria.dateTo)} 天` : `全部车辆 · ${inclusiveDays(criteria.dateFrom, criteria.dateTo)} 天`}
|
||||
expanded={!filtersCollapsed}
|
||||
status={`${criteria.vehicles.length ? `${criteria.vehicles.length} 辆` : '全部授权车辆'} · ${inclusiveDays(criteria.dateFrom, criteria.dateTo)} 天`}
|
||||
statusColor={criteria.vehicles.length ? 'blue' : 'grey'}
|
||||
collapsedLabel="修改"
|
||||
onToggle={() => setFiltersCollapsed((value) => !value)}
|
||||
>
|
||||
<form className={`v2-mileage-filter${filtersCollapsed ? ' is-mobile-collapsed' : ''}`} 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>
|
||||
<Button className="v2-primary-button" 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>
|
||||
</form>
|
||||
{validationError || criteriaError ? <p className="v2-mileage-validation" role="alert">{validationError || criteriaError}</p> : null}
|
||||
<SummaryRail data={statistics.data} criteria={criteria} fleetTotal={fleetVehicles.data?.total} loading={statistics.isLoading} />
|
||||
</WorkspaceFilterPanel>
|
||||
<div className="v2-mileage-discovery-shell">
|
||||
<WorkspaceCommandBar
|
||||
className="v2-mileage-command-bar"
|
||||
ariaLabel="里程查询工作区"
|
||||
title="车辆里程分析"
|
||||
description="按自然日对比车辆行驶里程与协议来源"
|
||||
status={`${criteria.vehicles.length ? `${criteria.vehicles.length} 辆` : '全部授权车辆'} · ${inclusiveDays(criteria.dateFrom, criteria.dateTo)} 天`}
|
||||
statusColor={criteria.vehicles.length ? 'blue' : 'grey'}
|
||||
meta={<span>{criteria.sources.find((source) => source.enabled)?.protocol ?? '未配置'} 优先</span>}
|
||||
/>
|
||||
<WorkspaceFilterPanel
|
||||
className="v2-mileage-query-panel"
|
||||
title="里程范围"
|
||||
description="车牌、自然日与里程数据源策略"
|
||||
mobileSummary={criteria.vehicles.length ? `已选 ${criteria.vehicles.length} 辆 · ${inclusiveDays(criteria.dateFrom, criteria.dateTo)} 天` : `全部车辆 · ${inclusiveDays(criteria.dateFrom, criteria.dateTo)} 天`}
|
||||
expanded={!filtersCollapsed}
|
||||
status={`${criteria.vehicles.length ? `${criteria.vehicles.length} 辆` : '全部授权车辆'} · ${inclusiveDays(criteria.dateFrom, criteria.dateTo)} 天`}
|
||||
statusColor={criteria.vehicles.length ? 'blue' : 'grey'}
|
||||
collapsedLabel="修改"
|
||||
onToggle={() => setFiltersCollapsed((value) => !value)}
|
||||
>
|
||||
<form className={`v2-mileage-filter${filtersCollapsed ? ' is-mobile-collapsed' : ''}`} 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>
|
||||
<Button className="v2-primary-button" 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>
|
||||
</form>
|
||||
{validationError || criteriaError ? <p className="v2-mileage-validation" role="alert">{validationError || criteriaError}</p> : null}
|
||||
<SummaryRail data={statistics.data} criteria={criteria} fleetTotal={fleetVehicles.data?.total} loading={statistics.isLoading} />
|
||||
</WorkspaceFilterPanel>
|
||||
</div>
|
||||
{statistics.isError || mileage.isError || fleetVehicles.isError ? <InlineError message={(statistics.error ?? mileage.error ?? fleetVehicles.error) instanceof Error ? (statistics.error ?? mileage.error ?? fleetVehicles.error as Error).message : '里程数据加载失败'} onRetry={() => { statistics.refetch(); mileage.refetch(); if (!hasVehicles) fleetVehicles.refetch(); }} /> : null}
|
||||
<Card className="v2-mileage-results" bodyStyle={{ padding: 0 }}>
|
||||
<WorkspacePanelHeader
|
||||
|
||||
@@ -63,7 +63,7 @@ describe('V2 production entry', () => {
|
||||
expect(corePageSources[name]).not.toContain("from '../shared/PageHeader'");
|
||||
expect(corePageSources[name]).not.toContain('<PageHeader');
|
||||
}
|
||||
for (const name of ['VehiclePage', 'TrackPage', 'AccessPage', 'OperationsPage', 'UsersPage']) {
|
||||
for (const name of ['VehiclePage', 'TrackPage', 'AccessPage', 'OperationsPage', 'StatisticsPage', 'UsersPage']) {
|
||||
expect(corePageSources[name]).toContain("from '../shared/WorkspaceCommandBar'");
|
||||
expect(corePageSources[name]).toContain('<WorkspaceCommandBar');
|
||||
}
|
||||
|
||||
@@ -12194,11 +12194,46 @@
|
||||
padding: 14px 18px 16px;
|
||||
}
|
||||
|
||||
.v2-mileage-query-panel.v2-workspace-filter-panel.semi-card {
|
||||
.v2-mileage-discovery-shell {
|
||||
display: grid;
|
||||
min-width: 0;
|
||||
flex: 0 0 auto;
|
||||
gap: 0;
|
||||
overflow: visible;
|
||||
border-color: #d8e3ef;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 8px 26px rgba(31, 53, 80, .055);
|
||||
border: 1px solid #d8e3ef;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
box-shadow: 0 9px 28px rgba(31, 53, 80, .055);
|
||||
}
|
||||
|
||||
.v2-mileage-discovery-shell > .v2-mileage-command-bar {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
height: 46px;
|
||||
min-height: 46px;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #e3eaf2;
|
||||
border-radius: 14px 14px 0 0;
|
||||
padding-inline: 13px 10px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.v2-mileage-command-bar .v2-workspace-command-meta {
|
||||
color: #748499;
|
||||
font-size: 10px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.v2-mileage-query-panel.v2-workspace-filter-panel.semi-card {
|
||||
width: 100%;
|
||||
overflow: visible;
|
||||
border: 0;
|
||||
border-radius: 0 0 14px 14px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.v2-mileage-discovery-shell > .v2-mileage-query-panel > .semi-card-body > .v2-workspace-filter-heading {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.v2-mileage-query-panel .v2-workspace-filter-heading {
|
||||
@@ -12560,7 +12595,16 @@
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.v2-mileage-discovery-shell {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.v2-mileage-discovery-shell > .v2-mileage-command-bar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.v2-mileage-query-panel.v2-workspace-filter-panel.semi-card {
|
||||
border: 1px solid #d8e3ef;
|
||||
border-radius: 11px;
|
||||
box-shadow: 0 5px 18px rgba(31, 53, 80, .05);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user