diff --git a/gerbil-manager-web/src/api/pedigree.ts b/gerbil-manager-web/src/api/pedigree.ts index a0e0659..6a3fe6d 100644 --- a/gerbil-manager-web/src/api/pedigree.ts +++ b/gerbil-manager-web/src/api/pedigree.ts @@ -3,20 +3,25 @@ * * Der Inzuchtkoeffizient wird serverseitig über die VOLLE Ahnentiefe berechnet * (Board-Entscheidung; UI zeigt 4 Generationen, Koeffizient zählt alle). - * Endpunkt entsteht in DATA-2-Folgearbeit — bis dahin antwortet er mit 404 und - * die UI zeigt einen „wird berechnet …“-Zustand. + * Endpunkt: FEAT-1b (InbreedingController, Wright-Pfadmethode). */ import { api, resources } from './client' -export interface InbreedingCoefficient { - /** Koeffizient nach Wright, 0..1. */ +/** Spiegelt GerbilManagerWebAPI.Genetics.InbreedingResult. */ +export interface InbreedingResult { + /** Koeffizient F nach Wright, 0..1. */ coefficient: number + /** F in Prozent (Server-Komfortfeld). */ + percent: number + /** Tiefste bekannte Ahnen-Generation (Eltern = 1; 0 = keine erfasst). */ + generationsAvailable: number + commonAncestors: { id: string; name: string; contribution: number }[] } export async function getInbreedingCoefficient(gerbilId: string): Promise { - const raw = await api.get( + const raw = await api.get( `${resources.gerbils}/${gerbilId}/inbreeding-coefficient`, ) - // Defensiv: Endpunkt-Form ist noch nicht final (nacktes number vs. Objekt). + // Defensiv gegen Vertragsdrift (nacktes number vs. Objekt). return typeof raw === 'number' ? raw : raw.coefficient } diff --git a/gerbil-manager-web/src/pages/StammbaumPage.tsx b/gerbil-manager-web/src/pages/StammbaumPage.tsx index 032ec3e..2964135 100644 --- a/gerbil-manager-web/src/pages/StammbaumPage.tsx +++ b/gerbil-manager-web/src/pages/StammbaumPage.tsx @@ -174,13 +174,14 @@ export default function StammbaumPage() { return () => observer.disconnect() }, [hasRoot]) - /* ── Ansicht (Zoom/Position): Wurzelkarte beim Laden zentriert ── */ + /* ── Ansicht (Zoom/Position): Wurzelkarte links, vertikal zentriert — + so sind die Eltern auch auf dem Smartphone sofort sichtbar. ── */ const defaultView = useMemo(() => { if (!size) return null const zoom = size.w < 520 ? 0.8 : 1 return { zoom, - translate: { x: Math.min(size.w / 2, CARD_W * zoom + 48), y: size.h / 2 }, + translate: { x: (CARD_W / 2) * zoom + 24, y: size.h / 2 }, } }, [size])