--- import SourceBadge from "./SourceBadge.astro"; import SectionHeading from "./SectionHeading.astro"; import { ago, kg, type PublicObservation } from "../lib/api"; const { signals } = Astro.props as { signals: PublicObservation[] }; const groups = [...signals.reduce((map, signal) => { // Similar fields do not establish that two sources describe the same catch. const key = JSON.stringify([signal.source_system, signal.id]); const current = map.get(key); if (!current) map.set(key, { ...signal, observations: [signal] }); else { current.observations.push(signal); current.last_seen_at = new Date(signal.last_seen_at) > new Date(current.last_seen_at) ? signal.last_seen_at : current.last_seen_at; current.missing_fields = [...new Set([...current.missing_fields, ...signal.missing_fields])]; if (signal.quality === "incomplete") current.quality = "incomplete"; } return map; }, new Map()).values()]; ---
{groups.map(signal => { const provenance = [...new Map(signal.observations.map(item => [`${item.source_system}|${item.source_url}`, item])).values()]; return
{provenance.map(item => )}
{signal.quality === "incomplete" ? "!" : "?"} {signal.quality === "incomplete" ? "Неполные данные" : "Ждёт проверки"}

{signal.fish_name}

{signal.waterbody_name}

Точка
{signal.x == null || signal.y == null ? "не указана" : `${signal.x}:${signal.y}`}
Вес
{signal.weight_g == null ? "не указан" : kg(signal.weight_g)}
Получено
{ago(signal.last_seen_at)}
{signal.observations.length > 1 &&

Совпали {signal.observations.length} наблюдения · все источники сохранены

}

{signal.missing_fields.length ? "Не хватает:" : "Статус:"} {signal.missing_fields.join(", ") || "проверяется соответствие справочнику"}

; })}