Refine history modal loading state and MGM chart gating

This commit is contained in:
2569718930@qq.com
2026-03-29 21:09:16 +08:00
parent d0e1bea941
commit efb5e426b7
3 changed files with 124 additions and 12 deletions
@@ -2237,6 +2237,46 @@
height: 100% !important;
}
.root :global(.history-modal .history-modal-loading) {
display: flex;
align-items: center;
justify-content: center;
min-height: 420px;
}
.root :global(.history-modal .history-loading-card) {
min-width: min(100%, 420px);
padding: 22px 26px;
gap: 16px;
border-radius: 22px;
}
.root :global(.history-modal .history-loading-card .loading-clouds),
.root :global(.history-modal .history-loading-card .loading-windfield) {
width: 180px;
}
.root :global(.history-modal .history-loading-radar) {
width: 86px;
height: 86px;
}
.root :global(.history-modal .history-loading-thermals) {
height: 22px;
gap: 6px;
}
.root :global(.history-modal .history-loading-copy strong) {
font-size: 12px;
letter-spacing: 0.18em;
}
.root :global(.history-modal .history-loading-copy span) {
max-width: 300px;
font-size: 12px;
line-height: 1.5;
}
.root :global(.history-modal .history-peak-reference) {
margin-top: 18px;
padding: 14px 16px;
@@ -2315,6 +2355,10 @@
height: 360px;
}
.root :global(.history-modal .history-modal-loading) {
min-height: 340px;
}
.root :global(.history-modal .history-peak-reference-scroll) {
max-height: 320px;
}
@@ -2360,6 +2404,26 @@
padding: 8px 10px 6px;
}
.root :global(.history-modal .history-modal-loading) {
min-height: 280px;
}
.root :global(.history-modal .history-loading-card) {
width: 100%;
min-width: 0;
padding: 18px 16px;
}
.root :global(.history-modal .history-loading-card .loading-clouds),
.root :global(.history-modal .history-loading-card .loading-windfield) {
width: 150px;
}
.root :global(.history-modal .history-loading-radar) {
width: 72px;
height: 72px;
}
.root :global(.history-modal .history-peak-reference) {
padding: 12px;
}
+53 -12
View File
@@ -28,6 +28,7 @@ function HistoryChart() {
);
const hasMgm =
store.selectedCity === "ankara" &&
summary.mgmSeriesComplete &&
summary.mgms.some((value) => value != null);
const hasBestBaseline =
Boolean(summary.bestModelName) &&
@@ -260,20 +261,58 @@ export function HistoryModal() {
: `${store.selectedDetail?.display_name || store.selectedCity || "该城市"}历史对账已按 NOAA ${noaaStationCode}${noaaStationName})结算口径对齐:采用该日最终完成质控后的最高整度摄氏值。`}
</div>
)}
<div className="history-stats">
{isLoading ? (
<span style={{ color: "var(--text-muted)" }}>
{t("history.loading")}
</span>
) : error ? (
{isLoading ? (
<div className="history-modal-loading">
<div className="loading-card history-loading-card">
<div className="loading-clouds" aria-hidden="true">
<span className="loading-cloud loading-cloud-1" />
<span className="loading-cloud loading-cloud-2" />
</div>
<div className="loading-windfield" aria-hidden="true">
<span className="loading-windline loading-windline-1" />
<span className="loading-windline loading-windline-2" />
<span className="loading-windline loading-windline-3" />
</div>
<div className="loading-radar history-loading-radar" aria-hidden="true">
<div className="loading-radar-core" />
<div className="loading-radar-ring loading-radar-ring-1" />
<div className="loading-radar-ring loading-radar-ring-2" />
<div className="loading-radar-sweep" />
<div className="loading-radar-blip loading-radar-blip-1" />
<div className="loading-radar-blip loading-radar-blip-2" />
</div>
<div className="loading-thermals history-loading-thermals" aria-hidden="true">
<span className="loading-thermal loading-thermal-1" />
<span className="loading-thermal loading-thermal-2" />
<span className="loading-thermal loading-thermal-3" />
<span className="loading-thermal loading-thermal-4" />
</div>
<div className="loading-copy history-loading-copy">
<strong>
{locale === "en-US"
? "Scanning archived settlement history"
: "正在扫描历史结算档案"}
</strong>
<span>
{locale === "en-US"
? "Reconciling settled highs, DEB traces, and baseline forecasts..."
: "正在对齐实测高温、DEB 轨迹与基线预报..."}
</span>
</div>
</div>
</div>
) : (
<>
<div className="history-stats">
{error ? (
<span style={{ color: "var(--accent-red)" }}>
{t("history.error")}
</span>
) : !summary.recentData.length ? (
) : !summary.recentData.length ? (
<span style={{ color: "var(--text-muted)" }}>
{t("history.empty")}
</span>
) : (
) : (
<>
<div className="h-stat-card">
<span className="label">{t("history.debHitRate")}</span>
@@ -314,10 +353,10 @@ export function HistoryModal() {
</span>
</div>
</>
)}
</div>
{!isLoading && !error && <HistoryChart />}
{!isLoading && !error && settledPeakRows.length > 0 && (
)}
</div>
{!error && <HistoryChart />}
{!error && settledPeakRows.length > 0 && (
<div className="history-peak-reference">
<div className="history-peak-reference-title">
{locale === "en-US"
@@ -374,6 +413,8 @@ export function HistoryModal() {
))}
</div>
</div>
)}
</>
)}
</div>
</div>
+7
View File
@@ -2247,6 +2247,12 @@ export function getHistorySummary(
});
}
const mgmSettledCount = settledData.reduce((count, row) => {
return toFinite(row.mgm) != null ? count + 1 : count;
}, 0);
const mgmSeriesComplete =
settledData.length >= 2 && mgmSettledCount === settledData.length;
return {
dates: recentData.map((row) => row.date),
debMae: debErrors.length
@@ -2274,6 +2280,7 @@ export function getHistorySummary(
hitRate: debErrors.length
? Number(((hits / debErrors.length) * 100).toFixed(0))
: null,
mgmSeriesComplete,
mgms: recentData.map((row) => row.mgm ?? null),
recentData,
settledCount: comparableSettledData.length,