feat(platform-web): add source quick actions
This commit is contained in:
@@ -245,6 +245,7 @@ export function VehicleDetail({
|
|||||||
))}
|
))}
|
||||||
</Space>
|
</Space>
|
||||||
<div className="vp-source-card-actions">
|
<div className="vp-source-card-actions">
|
||||||
|
<Space spacing={6} wrap>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
theme={activeProtocol === source.protocol ? 'solid' : 'light'}
|
theme={activeProtocol === source.protocol ? 'solid' : 'light'}
|
||||||
@@ -254,6 +255,25 @@ export function VehicleDetail({
|
|||||||
>
|
>
|
||||||
仅看 {source.protocol}
|
仅看 {source.protocol}
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
theme="light"
|
||||||
|
type="tertiary"
|
||||||
|
disabled={!source.hasHistory}
|
||||||
|
onClick={() => onOpenHistory(resolvedVIN, source.protocol)}
|
||||||
|
>
|
||||||
|
查看 {source.protocol} 历史
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
theme="light"
|
||||||
|
type="tertiary"
|
||||||
|
disabled={!source.hasMileage}
|
||||||
|
onClick={() => onOpenMileage(resolvedVIN, source.protocol)}
|
||||||
|
>
|
||||||
|
查看 {source.protocol} 里程
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1474,6 +1474,81 @@ test('opens history with the currently selected vehicle detail source', async ()
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('opens source-specific history directly from vehicle detail source card', async () => {
|
||||||
|
window.history.replaceState(null, '', '/#/detail?keyword=VIN001');
|
||||||
|
vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => {
|
||||||
|
const path = String(input);
|
||||||
|
if (path.includes('/api/vehicle-service')) {
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
json: async () => ({
|
||||||
|
data: {
|
||||||
|
vin: 'VIN001',
|
||||||
|
lookupKey: 'VIN001',
|
||||||
|
lookupResolved: true,
|
||||||
|
resolution: {
|
||||||
|
lookupKey: 'VIN001',
|
||||||
|
resolved: true,
|
||||||
|
vin: 'VIN001',
|
||||||
|
plate: '粤AG18312',
|
||||||
|
phone: '13307795425',
|
||||||
|
oem: 'G7s',
|
||||||
|
protocols: ['GB32960', 'JT808'],
|
||||||
|
online: true,
|
||||||
|
lastSeen: '2026-07-03 20:12:10'
|
||||||
|
},
|
||||||
|
realtimeSummary: {
|
||||||
|
vin: 'VIN001',
|
||||||
|
plate: '粤AG18312',
|
||||||
|
phone: '13307795425',
|
||||||
|
oem: 'G7s',
|
||||||
|
protocols: ['GB32960', 'JT808'],
|
||||||
|
sourceCount: 2,
|
||||||
|
onlineSourceCount: 2,
|
||||||
|
online: true,
|
||||||
|
primaryProtocol: 'GB32960',
|
||||||
|
longitude: 113.2,
|
||||||
|
latitude: 23.1,
|
||||||
|
speedKmh: 30,
|
||||||
|
socPercent: 78,
|
||||||
|
totalMileageKm: 100,
|
||||||
|
lastSeen: '2026-07-03 20:12:10'
|
||||||
|
},
|
||||||
|
sources: ['GB32960', 'JT808'],
|
||||||
|
sourceStatus: [
|
||||||
|
{ protocol: 'GB32960', online: true, lastSeen: '2026-07-03 20:12:10', hasRealtime: true, hasHistory: true, hasRaw: true, hasMileage: true },
|
||||||
|
{ protocol: 'JT808', online: true, lastSeen: '2026-07-03 20:12:08', hasRealtime: true, hasHistory: true, hasRaw: true, hasMileage: true }
|
||||||
|
],
|
||||||
|
realtime: [],
|
||||||
|
history: { items: [], total: 0, limit: 20, offset: 0 },
|
||||||
|
raw: { items: [], total: 0, limit: 10, offset: 0 },
|
||||||
|
mileage: { items: [], total: 0, limit: 20, offset: 0 },
|
||||||
|
quality: { items: [], total: 0, limit: 20, offset: 0 }
|
||||||
|
},
|
||||||
|
traceId: 'trace-test',
|
||||||
|
timestamp: 1783094400000
|
||||||
|
})
|
||||||
|
} as Response;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
json: async () => ({
|
||||||
|
data: { items: [], total: 0, limit: 10, offset: 0 },
|
||||||
|
traceId: 'trace-test',
|
||||||
|
timestamp: 1783094400000
|
||||||
|
})
|
||||||
|
} as Response;
|
||||||
|
});
|
||||||
|
|
||||||
|
render(<App />);
|
||||||
|
|
||||||
|
fireEvent.click(await screen.findByRole('button', { name: '查看 JT808 历史' }));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(window.location.hash).toBe('#/history?keyword=VIN001&protocol=JT808');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('opens vehicle service from an empty history query with the current filters', async () => {
|
test('opens vehicle service from an empty history query with the current filters', async () => {
|
||||||
window.history.replaceState(null, '', '/#/history?keyword=VIN404&protocol=JT808');
|
window.history.replaceState(null, '', '/#/history?keyword=VIN404&protocol=JT808');
|
||||||
vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => {
|
vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user