From ccbcbca0e8daa5557571bb8dae98c50cb7ab635a Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 27 Apr 2026 21:44:51 +0200 Subject: [PATCH] feat(stammbaum): inline add-relationship form in side panel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements the inline-edit affordance from docs/specs/stammbaum-tree-spec.html (section 3): a low-opacity "+ Beziehung hinzufügen" button below the direct relationships list expands into a compact form (type select, person typeahead, optional Von/Bis Jahr inputs, Abbrechen + Speichern). On save the form POSTs to /api/persons/{id}/relationships, reloads the panel's own data, and calls invalidateAll() so the tree picks up the new edge without a hard refresh. The panel takes a new canWrite prop, plumbed through from the +layout.server.ts data already exposed on page.data. Also pins the /stammbaum canvas to the viewport (-my-6 cancels
's py-6, h-[calc(100dvh-4.25rem)] subtracts the navbar) so the page no longer overflows below the fold. Co-Authored-By: Claude Opus 4.7 --- .../lib/components/StammbaumSidePanel.svelte | 169 +++++++++++++++++- frontend/src/routes/stammbaum/+page.svelte | 12 +- 2 files changed, 177 insertions(+), 4 deletions(-) diff --git a/frontend/src/lib/components/StammbaumSidePanel.svelte b/frontend/src/lib/components/StammbaumSidePanel.svelte index 56d758fb..fda9d48b 100644 --- a/frontend/src/lib/components/StammbaumSidePanel.svelte +++ b/frontend/src/lib/components/StammbaumSidePanel.svelte @@ -1,28 +1,55 @@
@@ -124,6 +203,92 @@ const topDerived = $derived(derivedRels.slice(0, 5)); {/each} {/if} + + {#if canWrite} + {#if !addFormOpen} + + {:else} +
+ + +
+ + +
+ {#if yearError} + + {/if} + {#if saveError} + + {/if} +
+ + +
+ + {/if} + {/if} {#if topDerived.length > 0} diff --git a/frontend/src/routes/stammbaum/+page.svelte b/frontend/src/routes/stammbaum/+page.svelte index bb6d076c..b7c1cacb 100644 --- a/frontend/src/routes/stammbaum/+page.svelte +++ b/frontend/src/routes/stammbaum/+page.svelte @@ -15,6 +15,7 @@ interface Props { let { data }: Props = $props(); const focusId = $derived(page.url.searchParams.get('focus')); +const canWrite = $derived(page.data.canWrite ?? false); let selectedId = $state(null); $effect(() => { @@ -34,7 +35,10 @@ function zoomOut() { } -
+ +
@@ -102,7 +106,11 @@ function zoomOut() {
{#if selectedNode} {/if}