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
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
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}`;
|
||||
}
|
||||
Reference in New Issue
Block a user