Move model views out of the dashboard utility bulk
Probability and multi-model view adapters were still embedded in dashboard-utils even though table, panel, modal, and city-card views use them as small pure selectors. This moves them into model-utils and keeps dashboard-utils re-export compatibility. Constraint: Preserve model/probability return shapes and existing fallback behavior. Rejected: Merge model-utils with chart-utils | model selectors and chart data preparation change at different rates. Confidence: high Scope-risk: narrow Reversibility: clean Tested: TypeScript diagnostics for model-utils, dashboard-utils, and PanelSections Tested: npm run build Not-tested: Bundle analyzer size comparison.
This commit is contained in:
@@ -26,10 +26,9 @@ import {
|
||||
import { getTemperatureChartData } from "@/lib/chart-utils";
|
||||
import {
|
||||
getFutureModalView,
|
||||
getModelView,
|
||||
getProbabilityView,
|
||||
getWeatherSummary,
|
||||
} from "@/lib/dashboard-utils";
|
||||
import { getModelView, getProbabilityView } from "@/lib/model-utils";
|
||||
import { getTodayPaceView } from "@/lib/pace-utils";
|
||||
import { dashboardClient } from "@/lib/dashboard-client";
|
||||
import {
|
||||
|
||||
@@ -8,10 +8,7 @@ import type {
|
||||
ScanOpportunityRow,
|
||||
} from "@/lib/dashboard-types";
|
||||
import { getLocalizedCityName } from "@/lib/dashboard-home-copy";
|
||||
import {
|
||||
getModelView,
|
||||
getProbabilityView,
|
||||
} from "@/lib/dashboard-utils";
|
||||
import { getModelView, getProbabilityView } from "@/lib/model-utils";
|
||||
import { getTodayPaceView } from "@/lib/pace-utils";
|
||||
import {
|
||||
formatTemperatureValue,
|
||||
|
||||
@@ -15,11 +15,10 @@ import {
|
||||
import { getTemperatureChartData } from "@/lib/chart-utils";
|
||||
import {
|
||||
getHeroMetaItems,
|
||||
getModelView,
|
||||
getProbabilityView,
|
||||
getRiskBadgeLabel,
|
||||
getWeatherSummary,
|
||||
} from "@/lib/dashboard-utils";
|
||||
import { getModelView, getProbabilityView } from "@/lib/model-utils";
|
||||
import {
|
||||
normalizeObservationSourceCode,
|
||||
normalizeObservationSourceLabel,
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
useCityMarketScan,
|
||||
} from "@/components/dashboard/scan-terminal/use-ai-city-card-data";
|
||||
import type { CityDetail, ScanOpportunityRow } from "@/lib/dashboard-types";
|
||||
import { getModelView } from "@/lib/dashboard-utils";
|
||||
import { getModelView } from "@/lib/model-utils";
|
||||
import { getTodayPaceView } from "@/lib/pace-utils";
|
||||
import { formatTemperatureValue } from "@/lib/temperature-utils";
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import { formatTafMarkerType } from "@/lib/taf-utils";
|
||||
import { normalizeHm } from "@/lib/time-utils";
|
||||
|
||||
export { getTemperatureChartData } from "@/lib/chart-utils";
|
||||
export { getModelView, getProbabilityView } from "@/lib/model-utils";
|
||||
export { getTodayPaceView } from "@/lib/pace-utils";
|
||||
export {
|
||||
formatTemperatureValue,
|
||||
@@ -246,56 +247,6 @@ export function getHeroMetaItems(detail: CityDetail, locale: Locale = "zh-CN") {
|
||||
return parts;
|
||||
}
|
||||
|
||||
export function getProbabilityView(detail: CityDetail, targetDate?: string | null) {
|
||||
const date = targetDate || detail.local_date;
|
||||
if (date === detail.local_date) {
|
||||
return {
|
||||
calibrationMode: detail.probabilities?.calibration_mode ?? null,
|
||||
calibrationVersion: detail.probabilities?.calibration_version ?? null,
|
||||
engine: detail.probabilities?.engine ?? null,
|
||||
mu: detail.probabilities?.mu ?? null,
|
||||
probabilities: detail.probabilities?.distribution || [],
|
||||
probabilitiesAll:
|
||||
detail.probabilities?.distribution_all ||
|
||||
detail.probabilities?.distribution ||
|
||||
[],
|
||||
shadowProbabilities: detail.probabilities?.shadow_distribution || [],
|
||||
shadowProbabilitiesAll:
|
||||
detail.probabilities?.shadow_distribution_all ||
|
||||
detail.probabilities?.shadow_distribution ||
|
||||
[],
|
||||
};
|
||||
}
|
||||
|
||||
const daily = detail.multi_model_daily?.[date];
|
||||
return {
|
||||
calibrationMode: null,
|
||||
calibrationVersion: null,
|
||||
engine: null,
|
||||
mu: daily?.deb?.prediction ?? null,
|
||||
probabilities: daily?.probabilities || [],
|
||||
probabilitiesAll: daily?.probabilities_all || daily?.probabilities || [],
|
||||
shadowProbabilities: [],
|
||||
shadowProbabilitiesAll: [],
|
||||
};
|
||||
}
|
||||
|
||||
export function getModelView(detail: CityDetail, targetDate?: string | null) {
|
||||
const date = targetDate || detail.local_date;
|
||||
const daily = detail.multi_model_daily?.[date];
|
||||
if (daily) {
|
||||
return {
|
||||
deb: daily.deb?.prediction ?? null,
|
||||
models: daily.models || {},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
deb: detail.deb?.prediction ?? null,
|
||||
models: detail.multi_model || {},
|
||||
};
|
||||
}
|
||||
|
||||
export function parseAiAnalysis(analysis: CityDetail["ai_analysis"]) {
|
||||
const fallback = {
|
||||
bullets: [] as string[],
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import type { CityDetail } from "@/lib/dashboard-types";
|
||||
|
||||
export function getProbabilityView(detail: CityDetail, targetDate?: string | null) {
|
||||
const date = targetDate || detail.local_date;
|
||||
if (date === detail.local_date) {
|
||||
return {
|
||||
calibrationMode: detail.probabilities?.calibration_mode ?? null,
|
||||
calibrationVersion: detail.probabilities?.calibration_version ?? null,
|
||||
engine: detail.probabilities?.engine ?? null,
|
||||
mu: detail.probabilities?.mu ?? null,
|
||||
probabilities: detail.probabilities?.distribution || [],
|
||||
probabilitiesAll:
|
||||
detail.probabilities?.distribution_all ||
|
||||
detail.probabilities?.distribution ||
|
||||
[],
|
||||
shadowProbabilities: detail.probabilities?.shadow_distribution || [],
|
||||
shadowProbabilitiesAll:
|
||||
detail.probabilities?.shadow_distribution_all ||
|
||||
detail.probabilities?.shadow_distribution ||
|
||||
[],
|
||||
};
|
||||
}
|
||||
|
||||
const daily = detail.multi_model_daily?.[date];
|
||||
return {
|
||||
calibrationMode: null,
|
||||
calibrationVersion: null,
|
||||
engine: null,
|
||||
mu: daily?.deb?.prediction ?? null,
|
||||
probabilities: daily?.probabilities || [],
|
||||
probabilitiesAll: daily?.probabilities_all || daily?.probabilities || [],
|
||||
shadowProbabilities: [],
|
||||
shadowProbabilitiesAll: [],
|
||||
};
|
||||
}
|
||||
|
||||
export function getModelView(detail: CityDetail, targetDate?: string | null) {
|
||||
const date = targetDate || detail.local_date;
|
||||
const daily = detail.multi_model_daily?.[date];
|
||||
if (daily) {
|
||||
return {
|
||||
deb: daily.deb?.prediction ?? null,
|
||||
models: daily.models || {},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
deb: detail.deb?.prediction ?? null,
|
||||
models: detail.multi_model || {},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user