feat: implement CitySelectorDropdown for ScanTerminalDashboard with multi-filter search and regional categorization

This commit is contained in:
2569718930@qq.com
2026-05-30 16:39:23 +08:00
parent a03b8095ee
commit 5470da6b3a
5 changed files with 79 additions and 7 deletions
@@ -233,6 +233,13 @@ export function runTests() {
chartCanvas.includes("canToggleRunwayDetails") && chartCanvas.includes("individualRunwaySeriesCount > 1"),
"single-runway charts must not show the runway-detail toggle because aggregate and individual views are visually redundant",
);
assert(
chartLogic.includes("HOURLY_DETAIL_REQUEST_TIMEOUT_MS = 12_000") &&
chartLogic.includes("fetchCityDetailWithTimeout") &&
chartLogic.includes("signal: controller.signal") &&
chartLogic.includes("controller.abort()"),
"city detail chart fetches must have a frontend timeout so panels cannot stay on 加载图表 forever",
);
assert(!chart.includes("3D"), "temperature chart UI must not expose a 3D/future-forecast mode");
assert(!chart.includes("build3DayChartData"), "temperature chart component must not render future prediction curves");
assert(
@@ -23,6 +23,10 @@ export function runTests() {
path.join(projectRoot, "components", "dashboard", "scan-terminal", "TemperatureChartCanvas.tsx"),
"utf8",
);
const citySelectorSource = fs.readFileSync(
path.join(projectRoot, "components", "dashboard", "scan-terminal", "CitySelectorDropdown.tsx"),
"utf8",
);
assert(
dashboardSource.includes("MAX_TERMINAL_CHARTS = 9"),
@@ -54,6 +58,22 @@ export function runTests() {
dashboardSource.includes("handleSelectCityForSlot(slotIndex, null);"),
"stale saved chart slots must render the empty city picker instead of a row=null Temperature Chart",
);
assert(
dashboardSource.includes("absolute left-1/2 top-12 z-50") &&
!dashboardSource.includes("top-1/2 -translate-x-1/2 -translate-y-1/2"),
"empty top-row slots must open the city selector downward so the search input is not clipped by the viewport header",
);
assert(
citySelectorSource.includes("max-h-[calc(100vh-72px)]") &&
citySelectorSource.includes("min-h-0 flex-1 overflow-y-auto"),
"city selector dropdown must cap its viewport height and keep the result list scrollable",
);
assert(
citySelectorSource.includes("MIN_DROPDOWN_TOP_PX") &&
citySelectorSource.includes("viewportNudgeY") &&
citySelectorSource.includes("getBoundingClientRect()"),
"city selector dropdown must nudge itself inside the viewport when opened from top-row chart cards",
);
assert(
chartSource.includes("setLiveTemp(null);") &&
chartSource.includes("lastAppliedPatchRevisionRef.current = 0;"),