From 1dffb430ace74e6031fa14c510f7a3d6b600a5f7 Mon Sep 17 00:00:00 2001
From: Marcel
Date: Fri, 29 May 2026 17:10:49 +0200
Subject: [PATCH] feat(stammbaum): centre-on-person control in the panel title
row (#692)
Add an onCentre control to StammbaumSidePanel (title row, both desktop aside
and mobile sheet). The page drives a one-shot centreOnId so StammbaumTree
recentres the canvas on the focal node (US-PAN-005). Also tighten the panel
spec's deathYear fixture to a valid type.
Co-Authored-By: Claude Opus 4.8
---
.../genealogy/StammbaumBottomSheet.svelte | 5 +-
.../genealogy/StammbaumSidePanel.svelte | 58 +++++++++++++------
.../StammbaumSidePanel.svelte.spec.ts | 19 +++++-
frontend/src/routes/stammbaum/+page.svelte | 15 ++++-
4 files changed, 76 insertions(+), 21 deletions(-)
diff --git a/frontend/src/lib/person/genealogy/StammbaumBottomSheet.svelte b/frontend/src/lib/person/genealogy/StammbaumBottomSheet.svelte
index 22cf3234..ac9ab3c2 100644
--- a/frontend/src/lib/person/genealogy/StammbaumBottomSheet.svelte
+++ b/frontend/src/lib/person/genealogy/StammbaumBottomSheet.svelte
@@ -10,9 +10,10 @@ interface Props {
node: PersonNodeDTO;
canWrite: boolean;
onClose: () => void;
+ onCentre?: () => void;
}
-let { node, canWrite, onClose }: Props = $props();
+let { node, canWrite, onClose, onCentre }: Props = $props();
// Swipe the sheet down past this threshold to dismiss it (Leonie).
const SWIPE_DISMISS_PX = 80;
@@ -70,5 +71,5 @@ function onKeydown(event: KeyboardEvent) {
-
+
diff --git a/frontend/src/lib/person/genealogy/StammbaumSidePanel.svelte b/frontend/src/lib/person/genealogy/StammbaumSidePanel.svelte
index c243de71..f0c9f429 100644
--- a/frontend/src/lib/person/genealogy/StammbaumSidePanel.svelte
+++ b/frontend/src/lib/person/genealogy/StammbaumSidePanel.svelte
@@ -14,10 +14,12 @@ type InferredRelationshipWithPersonDTO = components['schemas']['InferredRelation
interface Props {
node: PersonNodeDTO;
onClose: () => void;
+ /** When provided, a "centre on this person" control appears in the title row (US-PAN-005). */
+ onCentre?: () => void;
canWrite?: boolean;
}
-let { node, onClose, canWrite = false }: Props = $props();
+let { node, onClose, onCentre, canWrite = false }: Props = $props();
let directRels = $state([]);
let derivedRels = $state([]);
@@ -95,23 +97,45 @@ const topDerived = $derived(
{/if}
-
+
+
+
+
+
{#if error}
diff --git a/frontend/src/lib/person/genealogy/StammbaumSidePanel.svelte.spec.ts b/frontend/src/lib/person/genealogy/StammbaumSidePanel.svelte.spec.ts
index 4dda616b..142ccce2 100644
--- a/frontend/src/lib/person/genealogy/StammbaumSidePanel.svelte.spec.ts
+++ b/frontend/src/lib/person/genealogy/StammbaumSidePanel.svelte.spec.ts
@@ -11,7 +11,7 @@ const makeNode = () => ({
id: 'person-1',
displayName: 'Alice Müller',
birthYear: 1900,
- deathYear: null,
+ deathYear: undefined,
familyMember: true
});
@@ -50,6 +50,23 @@ describe('StammbaumSidePanel', () => {
await expect.element(page.getByText('Alice Müller')).toBeInTheDocument();
});
+ it('hides the centre control when onCentre is not provided', async () => {
+ render(StammbaumSidePanel, { node: makeNode(), onClose: vi.fn(), canWrite: false });
+ await expect
+ .element(page.getByRole('button', { name: 'Auf diese Person zentrieren' }))
+ .not.toBeInTheDocument();
+ });
+
+ it('calls onCentre when the centre control is clicked (US-PAN-005)', async () => {
+ const onCentre = vi.fn();
+ render(StammbaumSidePanel, { node: makeNode(), onClose: vi.fn(), onCentre, canWrite: false });
+ const btn = [...document.querySelectorAll('button')].find(
+ (b) => b.getAttribute('aria-label') === 'Auf diese Person zentrieren'
+ );
+ btn!.click();
+ expect(onCentre).toHaveBeenCalledOnce();
+ });
+
it('shows empty-relationships message when no direct relationships are loaded', async () => {
render(StammbaumSidePanel, { node: makeNode(), onClose: vi.fn(), canWrite: false });
await expect.element(page.getByText('Noch keine Beziehungen bekannt.')).toBeInTheDocument();
diff --git a/frontend/src/routes/stammbaum/+page.svelte b/frontend/src/routes/stammbaum/+page.svelte
index 084f60db..5e166e43 100644
--- a/frontend/src/routes/stammbaum/+page.svelte
+++ b/frontend/src/routes/stammbaum/+page.svelte
@@ -1,5 +1,5 @@