From fc023762725984374d24895f061fcabff3443405 Mon Sep 17 00:00:00 2001 From: lingniu Date: Sat, 4 Jul 2026 08:17:32 +0800 Subject: [PATCH] feat(platform): show active quality filters --- .../apps/web/src/pages/Quality.tsx | 15 +++++ .../apps/web/src/test/App.test.tsx | 65 +++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/vehicle-data-platform/apps/web/src/pages/Quality.tsx b/vehicle-data-platform/apps/web/src/pages/Quality.tsx index 1ea28934..f126e079 100644 --- a/vehicle-data-platform/apps/web/src/pages/Quality.tsx +++ b/vehicle-data-platform/apps/web/src/pages/Quality.tsx @@ -145,6 +145,11 @@ export function Quality({ const drillIssueType = (issueType: string) => { applyFilters({ ...filters, issueType }); }; + const filterSummary = [ + filters.keyword ? `关键词:${filters.keyword}` : '', + filters.protocol ? `数据来源:${qualityProtocolLabel(filters.protocol)}` : '', + filters.issueType ? `问题类型:${qualityIssueLabel(filters.issueType)}` : '' + ].filter(Boolean); return (
@@ -190,6 +195,16 @@ export function Quality({ + {filterSummary.length > 0 ? ( + + + {filterSummary.map((item) => ( + {item} + ))} + + + + ) : null} { expect(fetchMock).toHaveBeenCalledWith(expect.stringContaining('/api/quality/summary?keyword=%E7%B2%A4A&protocol=VEHICLE_SERVICE&issueType=NO_SOURCE'), undefined); }); +test('shows and clears current quality filters', async () => { + window.history.replaceState(null, '', '/#/quality?keyword=%E7%B2%A4A&protocol=VEHICLE_SERVICE&issueType=NO_SOURCE'); + const fetchMock = vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => { + const path = String(input); + if (path.includes('/api/ops/health')) { + return { + ok: true, + json: async () => ({ + data: { linkHealth: [], kafkaLag: 0, redisOnlineKeys: 0, tdengineWritable: true, mysqlWritable: true, runtime: { requestTimeoutMs: 5000 } }, + traceId: 'trace-test', + timestamp: 1783094400000 + }) + } as Response; + } + if (path.includes('/api/quality/summary')) { + return { + ok: true, + json: async () => ({ + data: { + issueVehicleCount: 1, + issueRecordCount: 1, + errorCount: 0, + warningCount: 1, + protocols: [{ name: 'VEHICLE_SERVICE', count: 1 }], + issueTypes: [{ name: 'NO_SOURCE', count: 1 }] + }, + traceId: 'trace-test', + timestamp: 1783094400000 + }) + } as Response; + } + if (path.includes('/api/quality/issues')) { + return { + ok: true, + json: async () => ({ + data: { items: [], total: 1, limit: 20, offset: 0 }, + traceId: 'trace-test', + timestamp: 1783094400000 + }) + } as Response; + } + return { + ok: true, + json: async () => ({ + data: { items: [], total: 0, limit: 20, offset: 0 }, + traceId: 'trace-test', + timestamp: 1783094400000 + }) + } as Response; + }); + + render(); + + expect(await screen.findByText('当前筛选')).toBeInTheDocument(); + expect(screen.getByText('关键词:粤A')).toBeInTheDocument(); + expect(screen.getByText('数据来源:车辆服务')).toBeInTheDocument(); + expect(screen.getByText('问题类型:暂无数据来源')).toBeInTheDocument(); + fireEvent.click(screen.getByRole('button', { name: '清空筛选' })); + + await waitFor(() => { + expect(fetchMock).toHaveBeenCalledWith(expect.stringContaining('/api/quality/issues?limit=20&offset=0'), undefined); + }); + expect(window.location.hash).toBe('#/quality'); +}); + test('copies shareable quality filter link', async () => { window.history.replaceState(null, '', '/#/quality?keyword=%E7%B2%A4A&protocol=VEHICLE_SERVICE&issueType=NO_SOURCE'); const writeText = vi.fn().mockResolvedValue(undefined);