feat: sync vehicle monitoring and accumulated platform updates
Add monitoring metrics, numeric sorting, report-time display, vehicle number labels, and map layout fixes. Include accumulated mileage, hydrogen, OneOS authentication, open platform, ingestion, deployment, and UI updates. Exclude temporary files, generated reports, and credentials. Validate frontend 632 tests and production build, API packages, vehicle-map tests, and release installer tests. Gateway suite has one pre-existing date-sensitive identity throttling test failure reproduced on the parent commit.
This commit is contained in:
@@ -14,6 +14,7 @@ const corePageSources = Object.fromEntries(['MonitorPage', 'VehiclePage', 'Track
|
||||
name,
|
||||
readFileSync(resolve(process.cwd(), `src/v2/pages/${name}.tsx`), 'utf8')
|
||||
]));
|
||||
const monitorTableSource = readFileSync(resolve(process.cwd(), 'src/v2/pages/MonitorVehicleTable.tsx'), 'utf8');
|
||||
const vehicleSearchSource = readFileSync(resolve(process.cwd(), 'src/v2/pages/VehicleSearchWorkspace.tsx'), 'utf8');
|
||||
const monitorVehicleDetailSource = readFileSync(resolve(process.cwd(), 'src/v2/pages/MonitorVehicleDetailCard.tsx'), 'utf8');
|
||||
const batchVehicleSearchSource = readFileSync(resolve(process.cwd(), 'src/v2/pages/BatchVehicleSearchDialog.tsx'), 'utf8');
|
||||
@@ -77,7 +78,7 @@ describe('V2 production entry', () => {
|
||||
expect(appV2Source).toContain('window.dispatchEvent(new Event(PLATFORM_READY_EVENT))');
|
||||
});
|
||||
|
||||
test('keeps core business pages on shared Semi UI controls and page hierarchy', () => {
|
||||
test('keeps business page hierarchy while migrating shared controls to shadcn', () => {
|
||||
for (const source of Object.values(corePageSources)) {
|
||||
expect(source).toContain("from '@douyinfe/semi-ui'");
|
||||
expect(source).toContain('<Button');
|
||||
@@ -110,9 +111,7 @@ describe('V2 production entry', () => {
|
||||
expect(corePageSources.VehiclePage).toContain("lazy(() => import('./VehicleSearchWorkspace'))");
|
||||
expect(vehicleSearchSource).toContain("from '../shared/WorkspaceCommandBar'");
|
||||
expect(vehicleSearchSource).toContain('<WorkspaceCommandBar');
|
||||
expect(vehicleSearchSource).toContain("from '../shared/WorkspaceMetricRail'");
|
||||
expect(vehicleSearchSource).toContain('<WorkspaceMetricRail');
|
||||
expect(vehicleSearchSource).toContain('className="v2-vehicle-directory-metric-rail"');
|
||||
expect(vehicleSearchSource).toContain('aria-label="车辆目录摘要"');
|
||||
expect(vehicleSearchSource).not.toContain('className="v2-vehicle-directory-summary"');
|
||||
expect(corePageSources.VehiclePage).toContain("lazy(() => import('./VehicleArchiveCard'))");
|
||||
expect(vehicleArchiveSource).toContain('<Select');
|
||||
@@ -179,9 +178,9 @@ describe('V2 production entry', () => {
|
||||
expect(corePageSources.MonitorPage).not.toContain('<aside className="v2-vehicle-detail"');
|
||||
expect(corePageSources.MonitorPage).not.toContain('<aside className="v2-detail-peek"');
|
||||
expect(corePageSources.MonitorPage).not.toContain('<section className="v2-event-strip"');
|
||||
expect(corePageSources.MonitorPage).toContain('<Table className="v2-monitor-table"');
|
||||
expect(corePageSources.MonitorPage).toContain('<PanelEmpty className="v2-monitor-table-empty"');
|
||||
expect(corePageSources.MonitorPage).toContain('<PanelLoading className="v2-monitor-table-loading"');
|
||||
expect(monitorTableSource).toContain('<Table className="business-data-table"');
|
||||
expect(monitorTableSource).toContain('<PanelEmpty className="v2-monitor-table-empty"');
|
||||
expect(monitorTableSource).toContain('<PanelLoading className="v2-monitor-table-loading"');
|
||||
expect(corePageSources.MonitorPage).toContain('title="正在加载车辆详情"');
|
||||
expect(corePageSources.MonitorPage).not.toContain('<table><thead><tr><th>车辆</th>');
|
||||
expect(sourceEvidenceSource).toContain("import { Button, Card, Input, Tag } from '@douyinfe/semi-ui'");
|
||||
@@ -219,7 +218,8 @@ describe('V2 production entry', () => {
|
||||
expect(corePageSources.HistoryPage).toContain('className="v2-history-summary-rail"');
|
||||
expect(corePageSources.HistoryPage).not.toContain('v2-history-context-card');
|
||||
expect(corePageSources.HistoryPage).not.toContain('v2-history-metric-scroll');
|
||||
expect(corePageSources.HistoryPage).toContain('<WorkspaceFilterPanel');
|
||||
expect(corePageSources.HistoryPage).toContain('<Card className="v2-history-filter-card"');
|
||||
expect(corePageSources.HistoryPage).not.toContain('<WorkspaceFilterPanel');
|
||||
expect(corePageSources.HistoryPage).toContain('<WorkspaceCommandBar');
|
||||
expect(corePageSources.HistoryPage).toContain('className="v2-history-discovery-shell"');
|
||||
expect(corePageSources.HistoryPage).toContain('className="v2-history-filter-card"');
|
||||
@@ -268,7 +268,7 @@ describe('V2 production entry', () => {
|
||||
expect(corePageSources.AlertsPage).toContain('className={`v2-alert-event-table');
|
||||
expect(corePageSources.AlertsPage).toContain('detailTriggerRow({');
|
||||
expect(corePageSources.AlertsPage).not.toContain('<table><thead><tr><th />');
|
||||
expect(corePageSources.AlertsPage).toContain('className="v2-alert-filter-card"');
|
||||
expect(corePageSources.AlertsPage).toContain('aria-label="筛选事件"');
|
||||
expect(corePageSources.AlertsPage).not.toContain('<section className="v2-alert-table-card"');
|
||||
expect(corePageSources.AlertsPage).not.toContain('<aside className="v2-alert-inspector"');
|
||||
expect(corePageSources.AlertsPage).not.toContain('<select');
|
||||
@@ -315,7 +315,7 @@ describe('V2 production entry', () => {
|
||||
expect(corePageSources.AccessPage).toContain('className="v2-access-governance-sidesheet"');
|
||||
expect(corePageSources.AccessPage).toContain('<WorkspaceSideSheet');
|
||||
expect(corePageSources.AccessPage).toContain('variant="config"');
|
||||
expect(corePageSources.AccessPage).toContain('className="v2-access-filter-card-v3"');
|
||||
expect(corePageSources.AccessPage).toContain('aria-label="接入筛选"');
|
||||
expect(corePageSources.AccessPage).not.toContain('<section className="v2-access-table-v3"');
|
||||
expect(corePageSources.AccessPage).not.toContain('<aside className="v2-access-inspector-v3"');
|
||||
expect(corePageSources.AccessPage).toContain('<Card key={row.vin} className={`v2-access-mobile-card');
|
||||
@@ -412,7 +412,7 @@ describe('V2 production entry', () => {
|
||||
expect(corePageSources.OperationsPage).toContain('<Input');
|
||||
expect(corePageSources.OperationsPage).toContain('<Card className="v2-source-diagnostic"');
|
||||
expect(corePageSources.OperationsPage).toContain('<Card className="v2-ops-overview"');
|
||||
expect(corePageSources.OperationsPage).toContain("from '../shared/WorkspaceMetricRail'");
|
||||
expect(corePageSources.OperationsPage).toContain("from './GovernanceStatusStrip'");
|
||||
expect(corePageSources.OperationsPage).toContain('<WorkspaceMetricRail');
|
||||
expect(workspaceMetricRailSource).toContain("variant: 'queue'");
|
||||
expect(workspaceMetricRailSource).not.toContain('CardGroup');
|
||||
@@ -423,7 +423,7 @@ describe('V2 production entry', () => {
|
||||
expect(corePageSources.OperationsPage).toContain('<article className={`v2-ops-link-card');
|
||||
expect(corePageSources.OperationsPage).not.toContain('<Card className={`v2-ops-link-card');
|
||||
expect(corePageSources.OperationsPage).toContain('<Descriptions className="v2-ops-runtime-descriptions"');
|
||||
expect(corePageSources.OperationsPage).toContain('<PanelEmpty className="v2-ops-capacity-empty"');
|
||||
expect(corePageSources.OperationsPage).toContain('<div className="governance-capacity-ok" role="status"');
|
||||
expect(corePageSources.OperationsPage).toContain('<CardGroup className="v2-ops-source-list"');
|
||||
expect(corePageSources.OperationsPage).toContain('<SourceReadinessCard source={source}');
|
||||
expect(corePageSources.OperationsPage).toContain('<Collapse className="v2-ops-source-collapse"');
|
||||
@@ -548,15 +548,15 @@ describe('V2 production entry', () => {
|
||||
expect(corePageSources[name]).toContain("from '../shared/WorkspaceSideSheet'");
|
||||
expect(corePageSources[name]).toContain('<WorkspaceSideSheet');
|
||||
}
|
||||
expect(workspaceSideSheetSource).toContain("from '@douyinfe/semi-ui'");
|
||||
expect(workspaceSideSheetSource).toContain('<SideSheet');
|
||||
expect(workspaceSideSheetSource).toContain('className={sheetClassName}');
|
||||
expect(workspaceSideSheetSource).toContain("from '@/components/ui/sheet'");
|
||||
expect(workspaceSideSheetSource).toContain('<SheetContent');
|
||||
expect(workspaceSideSheetSource).toContain('business-sheet');
|
||||
expect(workspaceStyles).toContain(':is(.v2-workspace-config-sidesheet, .v2-workspace-filter-sidesheet) .semi-sidesheet-inner {');
|
||||
expect(workspaceStyles).toContain('.v2-workspace-filter-sidesheet .v2-workspace-config-title-icon {');
|
||||
expect(workspaceStyles).toContain('.v2-workspace-config-summary {');
|
||||
expect(workspaceStyles).toContain('.v2-workspace-config-footer {');
|
||||
expect(workspaceDialogSource).toContain("from '@douyinfe/semi-ui'");
|
||||
expect(workspaceDialogSource).toContain('<Modal');
|
||||
expect(workspaceDialogSource).toContain("from '@/components/ui/dialog'");
|
||||
expect(workspaceDialogSource).toContain('<DialogContent');
|
||||
expect(workspaceDialogSource).toContain('export function WorkspaceConfirmDialog');
|
||||
expect(appShellSource).toContain('<WorkspaceDialog');
|
||||
expect(appShellSource).not.toContain('<Modal');
|
||||
@@ -585,7 +585,7 @@ describe('V2 production entry', () => {
|
||||
expect(corePageSources.MonitorPage).toContain('v2-monitor-qr-sidesheet');
|
||||
expect(corePageSources.MonitorPage).not.toContain('<Modal');
|
||||
expect(corePageSources.MonitorPage).not.toContain('v2-monitor-qr-backdrop');
|
||||
expect(batchVehicleSearchSource).toContain('<TextArea');
|
||||
expect(batchVehicleSearchSource).toContain('<Textarea');
|
||||
expect(corePageSources.MonitorPage).toContain('<SegmentedTabs');
|
||||
expect(corePageSources.MonitorPage).toContain('ariaLabel="监控视图"');
|
||||
expect(corePageSources.MonitorPage).toContain('variant="filled"');
|
||||
@@ -615,15 +615,15 @@ describe('V2 production entry', () => {
|
||||
expect(corePageSources.MonitorPage).toContain('<WorkspaceMetricRail');
|
||||
expect(corePageSources.MonitorPage).toContain('className="v2-monitor-summary-rail"');
|
||||
expect(corePageSources.MonitorPage).not.toContain('className="v2-kpis"');
|
||||
expect(corePageSources.MonitorPage).toContain('<Card className="v2-monitor-table-panel"');
|
||||
expect(monitorTableSource).toContain('<Card className="v2-monitor-table-panel"');
|
||||
expect(corePageSources.MonitorPage).not.toContain('<section className="v2-filterbar"');
|
||||
expect(corePageSources.MonitorPage).not.toContain('<section className="v2-kpis"');
|
||||
expect(corePageSources.MonitorPage).not.toContain('<section className="v2-monitor-table-panel"');
|
||||
expect(corePageSources.MonitorPage).toContain('<Card className={`v2-monitor-mobile-card');
|
||||
expect(monitorTableSource).toContain('<Card className={`v2-monitor-mobile-card');
|
||||
expect(reconciliationSource).toContain("from '@douyinfe/semi-ui'");
|
||||
expect(reconciliationSource).toContain('<RadioGroup');
|
||||
expect(reconciliationSource).toContain('<Select');
|
||||
expect(reconciliationSource).toContain('<Card className="v2-reconcile-center"');
|
||||
expect(reconciliationSource).toContain('<Card className="v2-reconcile-center governance-queue"');
|
||||
expect(reconciliationSource).toContain('<WorkspaceMetricRail');
|
||||
expect(reconciliationSource).toContain('variant="queue"');
|
||||
expect(reconciliationSource).not.toContain('v2-reconcile-kpi-card');
|
||||
@@ -647,9 +647,9 @@ describe('V2 production entry', () => {
|
||||
expect(sourceEvidenceSource).toContain('<Button');
|
||||
expect(mobileFilterToggleSource).toContain("from '@douyinfe/semi-ui'");
|
||||
expect(mobileFilterToggleSource).toContain('<Button');
|
||||
expect(segmentedTabsSource).toContain("from '@douyinfe/semi-ui'");
|
||||
expect(segmentedTabsSource).toContain('role="tablist"');
|
||||
expect(segmentedTabsSource).toContain('role="tab"');
|
||||
expect(segmentedTabsSource).toContain("from '@/components/ui/tabs'");
|
||||
expect(segmentedTabsSource).toContain('<TabsList');
|
||||
expect(segmentedTabsSource).toContain('<TabsTrigger');
|
||||
for (const name of ['VehiclePage', 'AlertsPage', 'TrackPage', 'OperationsPage']) {
|
||||
expect(corePageSources[name]).toContain("from '../shared/SegmentedTabs'");
|
||||
expect(corePageSources[name]).toContain('<SegmentedTabs');
|
||||
@@ -663,8 +663,8 @@ describe('V2 production entry', () => {
|
||||
expect(tablePaginationSource).toContain('currentPage={safePage}');
|
||||
expect(tablePaginationSource).toContain('onPageChange={onPageChange}');
|
||||
for (const name of ['MonitorPage', 'AlertsPage', 'HistoryPage', 'AccessPage', 'StatisticsPage']) {
|
||||
expect(corePageSources[name]).toContain("from '../shared/TablePagination'");
|
||||
expect(corePageSources[name]).toContain('<TablePagination');
|
||||
expect(name === 'MonitorPage' ? monitorTableSource : corePageSources[name]).toContain("from '../shared/TablePagination'");
|
||||
expect(name === 'MonitorPage' ? monitorTableSource : corePageSources[name]).toContain('<TablePagination');
|
||||
}
|
||||
expect(reconciliationSource).toContain("from '../shared/TablePagination'");
|
||||
expect(reconciliationSource).toContain('<TablePagination');
|
||||
@@ -685,11 +685,11 @@ describe('V2 production entry', () => {
|
||||
expect(source).toContain('<MapRetryAction');
|
||||
expect(source).not.toContain('><IconRefresh />重新加载地图</button>');
|
||||
}
|
||||
expect(corePageSources.AccessPage).toContain("from '../shared/WorkspaceMetricRail'");
|
||||
expect(corePageSources.AccessPage).toContain("from './GovernanceStatusStrip'");
|
||||
expect(corePageSources.AccessPage).toContain('<WorkspaceMetricRail');
|
||||
expect(corePageSources.AlertsPage).not.toContain("from '../shared/WorkspaceMetricRail'");
|
||||
expect(corePageSources.AlertsPage).toContain('className="v2-event-status-tabs"');
|
||||
expect(corePageSources.OperationsPage).toContain("from '../shared/WorkspaceMetricRail'");
|
||||
expect(corePageSources.OperationsPage).toContain("from './GovernanceStatusStrip'");
|
||||
expect(corePageSources.OperationsPage).toContain('<WorkspaceMetricRail');
|
||||
expect(corePageSources.HistoryPage).toContain('className="v2-history-result-meta"');
|
||||
expect(corePageSources.AlertsPage).toContain('function EventExecutionTag');
|
||||
@@ -718,18 +718,24 @@ describe('V2 production entry', () => {
|
||||
expect(workspaceStyles).toContain('bottom: 110px;');
|
||||
expect(workspaceFilterPanelSource).toContain("from './MobileFilterToggle'");
|
||||
expect(workspaceFilterPanelSource).toContain('<MobileFilterToggle');
|
||||
for (const name of ['HistoryPage', 'AlertsPage', 'AccessPage', 'StatisticsPage', 'UsersPage', 'OperationsPage']) {
|
||||
for (const name of ['StatisticsPage', 'OperationsPage']) {
|
||||
expect(corePageSources[name]).toContain("from '../shared/WorkspaceFilterPanel'");
|
||||
expect(corePageSources[name]).toContain('<WorkspaceFilterPanel');
|
||||
}
|
||||
// Compact query surfaces keep named controls and responsive filter entry points
|
||||
// without requiring an extra card heading above the result workspace.
|
||||
for (const [name, label] of [['HistoryPage', '查询范围'], ['AlertsPage', '筛选事件'], ['AccessPage', '接入筛选'], ['UsersPage', '客户账号筛选']]) {
|
||||
expect(corePageSources[name]).toContain(`aria-label="${label}"`);
|
||||
expect(corePageSources[name]).toMatch(/<(?:MobileFilter|WorkspaceSideSheet)/);
|
||||
}
|
||||
expect(vehicleSearchSource).toContain("from '../shared/WorkspaceFilterPanel'");
|
||||
expect(vehicleSearchSource).toContain('<WorkspaceFilterPanel');
|
||||
expect(tablePaginationSource).toContain('<Pagination');
|
||||
});
|
||||
|
||||
test('keeps the shared desktop and mobile application shell on Semi UI navigation primitives', () => {
|
||||
expect(appShellSource).toContain('<Layout className="v2-shell">');
|
||||
expect(appShellSource).toContain('<Nav className="v2-navigation"');
|
||||
test('keeps desktop navigation and mobile entry points in the shared shell', () => {
|
||||
expect(appShellSource).toContain('<Layout className="v2-shell business-shell" data-density={density}>');
|
||||
expect(appShellSource).toContain('<nav className="business-navigation"');
|
||||
expect(appShellSource).toContain('className="v2-mobile-more-sidesheet"');
|
||||
expect(appShellSource.match(/<WorkspaceSideSheet/g)).toHaveLength(2);
|
||||
expect(appShellSource).not.toContain('<SideSheet');
|
||||
@@ -743,8 +749,8 @@ describe('V2 production entry', () => {
|
||||
expect(authGateSource.match(/<PasswordInput/g)).toHaveLength(1);
|
||||
expect(authGateSource).not.toContain('<Tabs');
|
||||
expect(authGateSource).not.toContain('运维令牌');
|
||||
expect(authGateSource).toContain('aria-label="账号密码登录"');
|
||||
expect(authGateSource).toContain('>账号密码登录</Tag>');
|
||||
expect(authGateSource).toContain("'中台账号登录'");
|
||||
expect(authGateSource).toContain("'OneOS 统一身份' : '中台账号'");
|
||||
expect(passwordInputSource).toContain('<Input');
|
||||
expect(passwordInputSource).toContain('<Button');
|
||||
expect(passwordInputSource).toContain("`${visible ? '隐藏' : '显示'}${visibilityLabel}`");
|
||||
|
||||
Reference in New Issue
Block a user