Files
PolyWeather/frontend/components/dashboard/opportunity-model-summary.ts
T
2569718930@qq.com 2b1d7c0b65 Improve dashboard maintainability before the next release
The dashboard had several oversized orchestration, component, and CSS files that made product-copy changes and mobile/performance work risky. This refactor preserves behavior while splitting scan terminal CSS, opportunity helpers, future forecast panels, history/detail charts, and probability/model sections into smaller ownership boundaries.

Constraint: No user-visible version bump because this batch is architecture and performance cleanup, not a release announcement.

Rejected: Rewrite dashboard state management in the same batch | too broad for a safe upload after CSS and component splitting.

Confidence: high

Scope-risk: moderate

Reversibility: clean

Directive: Keep new component/CSS boundaries instead of moving product copy back into the large dashboard files.

Tested: npm run build; npm run test:business; git diff --check

Not-tested: Browser visual smoke test after push
2026-04-28 20:19:17 +08:00

47 lines
1.6 KiB
TypeScript

import type { ScanOpportunityRow } from "@/lib/dashboard-types";
import { formatTemperatureValue } from "@/lib/temperature-utils";
export function formatModelSources(row: ScanOpportunityRow, tempSymbol?: string | null) {
const sources = row.model_cluster_sources || {};
return Object.entries(sources)
.filter(([, value]) => value != null && Number.isFinite(Number(value)))
.sort(([left], [right]) => left.localeCompare(right))
.map(([name, value]) => ({
name,
value: formatTemperatureValue(Number(value), tempSymbol, { digits: 1 }),
}));
}
export function formatModelClusterRange(
sources?: Record<string, number | null> | null,
tempSymbol?: string | null,
) {
const values = Object.values(sources || {})
.map((value) => Number(value))
.filter((value) => Number.isFinite(value));
if (!values.length) return "--";
const low = Math.min(...values);
const high = Math.max(...values);
if (Math.abs(low - high) < 0.05) {
return formatTemperatureValue(low, tempSymbol, { digits: 1 });
}
return `${formatTemperatureValue(low, tempSymbol, { digits: 1 })} ~ ${formatTemperatureValue(high, tempSymbol, { digits: 1 })}`;
}
export function getModelSourceSummary(
row: ScanOpportunityRow,
locale: string,
tempSymbol?: string | null,
) {
const sources = formatModelSources(row, tempSymbol);
if (!sources.length) {
return locale === "en-US"
? "model cluster pending"
: "模型集群暂未回传";
}
const shown = sources.map((item) => `${item.name} ${item.value}`).join(" / ");
return locale === "en-US"
? `all models: ${shown}`
: `全部模型:${shown}`;
}