fix: clarify blocked source status

This commit is contained in:
ik
2026-09-21 07:37:32 +07:00
parent 3b4557b549
commit 2ed28266df
5 changed files with 19 additions and 6 deletions
+1 -1
View File
@@ -34,7 +34,7 @@ export type MediaAsset = { id: string; entity_type: "fish" | "waterbody" | "tack
export const spotPath = (item: Pick<Activity, "waterbody_slug" | "x" | "y">) => `/spots/${item.waterbody_slug}-${item.x}x${item.y}`;
export { activityLevel, ago, freshnessStatus, kg, plural } from "./presentation";
export { activityLevel, ago, freshnessStatus, kg, plural, sourceStatusLabel } from "./presentation";
const base = process.env.API_INTERNAL_URL || import.meta.env.API_INTERNAL_URL || "http://localhost:8000";
+8
View File
@@ -27,3 +27,11 @@ export function freshnessStatus(value: string | null | undefined, now = Date.now
if (!Number.isFinite(timestamp)) return "unknown";
return now - timestamp > 48 * 60 * 60 * 1000 ? "stale" : "fresh";
}
export function sourceStatusLabel(status: string) {
const labels: Record<string, string> = {
healthy: "Актуален", stale: "Данные устарели", temporarily_limited: "Источник временно ограничен",
source_changed: "Источник изменился", waiting: "Ожидает запуска", disabled: "Выключен",
};
return labels[status] ?? "Состояние не определено";
}
+2 -3
View File
@@ -4,13 +4,12 @@ import SourceBadge from "../components/SourceBadge.astro";
import DataLegend from "../components/DataLegend.astro";
import PageHero from "../components/PageHero.astro";
import StatePanel from "../components/StatePanel.astro";
import { ago, api, plural, type SourceStatus } from "../lib/api";
import { ago, api, plural, sourceStatusLabel, type SourceStatus } from "../lib/api";
let sources: SourceStatus[] = [], unavailable = false;
try { sources = await api<SourceStatus[]>("/api/v1/source-status"); } catch { unavailable = true; }
const labels = { healthy:"Актуален", stale:"Данные устарели", temporarily_limited:"Временная пауза", source_changed:"Источник изменился", waiting:"Ожидает запуска", disabled:"Выключен" };
---
<Layout title="Состояние источников — RF4 Spotter" description="Текущее безопасное состояние источников данных RF4 Spotter.">
<PageHero eyebrow="Прозрачность данных" title="Статус источников" description="Пауза или изменение страницы не удаляют уже опубликованные данные." />
{unavailable ? <StatePanel tone="unavailable" title="Статус временно недоступен" description="Данные о состоянии источников не получены. Публичные наблюдения при этом не изменяются." /> : <section class="source-health-grid content-grid">{sources.map(source => <article data-status={source.status}><div><SourceBadge source={source.source_system}/><span class="health-state"><i></i>{labels[source.status]}</span></div><h2>{source.name}</h2><strong>{source.observations} {plural(source.observations,["наблюдение","наблюдения","наблюдений"])}</strong><p>{source.last_success_at ? `Последнее успешное обновление ${ago(source.last_success_at)}` : "Успешных запусков пока нет"}</p></article>)}</section>}
{unavailable ? <StatePanel tone="unavailable" title="Статус временно недоступен" description="Данные о состоянии источников не получены. Публичные наблюдения при этом не изменяются." /> : <section class="source-health-grid content-grid">{sources.map(source => <article data-status={source.status}><div><SourceBadge source={source.source_system}/><span class="health-state"><i></i>{sourceStatusLabel(source.status)}</span></div><h2>{source.name}</h2><strong>{source.observations} {plural(source.observations,["наблюдение","наблюдения","наблюдений"])}</strong><p>{source.status === "temporarily_limited" ? "Источник ограничен; опубликованные данные сохранены." : source.last_success_at ? `Последнее успешное обновление ${ago(source.last_success_at)}` : "Успешных запусков пока нет"}</p></article>)}</section>}
<DataLegend />
</Layout>