From 446611e3cc90663b12cf6ca2356d203c11bb5161 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 15 Jun 2026 08:16:10 +0200 Subject: [PATCH] =?UTF-8?q?feat(person):=20add=20a=20curator=20"Ereignis?= =?UTF-8?q?=20f=C3=BCr=20diese=20Person"=20link=20to=20PersonCard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A curator on a person's page can now seed a timeline event from that person: a gated link to #781's /zeitstrahl/events/new?personId={id}, which prefills the person and returns to /persons/{id} on save. Hidden for a Reader. New i18n key person_add_event in de/en/es. Refs #842 Co-Authored-By: Claude Opus 4.8 --- frontend/messages/de.json | 1 + frontend/messages/en.json | 1 + frontend/messages/es.json | 1 + .../src/routes/persons/[id]/PersonCard.svelte | 12 ++++++- .../persons/[id]/PersonCard.svelte.spec.ts | 32 +++++++++++++++++++ 5 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 frontend/src/routes/persons/[id]/PersonCard.svelte.spec.ts diff --git a/frontend/messages/de.json b/frontend/messages/de.json index c6eccdf1..6be0122c 100644 --- a/frontend/messages/de.json +++ b/frontend/messages/de.json @@ -188,6 +188,7 @@ "person_hint_generation": "Generation in der Familie (G 0 = älteste Generation)", "person_year_error": "Bitte eine vierstellige Jahreszahl eingeben", "person_years_error_order": "Geburtsjahr muss vor dem Todesjahr liegen", + "person_add_event": "Ereignis für diese Person", "person_docs_heading": "Gesendete Dokumente", "person_no_docs": "Diese Person ist noch nicht als Absender verknüpft.", "person_received_docs_heading": "Empfangene Dokumente", diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 0bfeb8e1..b07fe58e 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -188,6 +188,7 @@ "person_hint_generation": "Generation within the family (G 0 = oldest generation)", "person_year_error": "Please enter a four-digit year", "person_years_error_order": "Birth year must be before death year", + "person_add_event": "Add event for this person", "person_docs_heading": "Sent documents", "person_no_docs": "This person has not yet been linked as a sender.", "person_received_docs_heading": "Received documents", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 37ee161e..2048c1f6 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -188,6 +188,7 @@ "person_hint_generation": "Generación dentro de la familia (G 0 = generación más antigua)", "person_year_error": "Introduzca un año de cuatro dígitos", "person_years_error_order": "El año de nacimiento debe ser anterior al año de fallecimiento", + "person_add_event": "Añadir evento para esta persona", "person_docs_heading": "Documentos enviados", "person_no_docs": "Esta persona aún no está vinculada como remitente.", "person_received_docs_heading": "Documentos recibidos", diff --git a/frontend/src/routes/persons/[id]/PersonCard.svelte b/frontend/src/routes/persons/[id]/PersonCard.svelte index fd67c8f6..3f0284c9 100644 --- a/frontend/src/routes/persons/[id]/PersonCard.svelte +++ b/frontend/src/routes/persons/[id]/PersonCard.svelte @@ -128,7 +128,8 @@ const deathText = $derived(formatLifeDate(person.deathDate, person.deathDatePrec {/if} - + {#if canWrite} {m.btn_edit()} + + + {m.person_add_event()} + {/if} diff --git a/frontend/src/routes/persons/[id]/PersonCard.svelte.spec.ts b/frontend/src/routes/persons/[id]/PersonCard.svelte.spec.ts new file mode 100644 index 00000000..70386e65 --- /dev/null +++ b/frontend/src/routes/persons/[id]/PersonCard.svelte.spec.ts @@ -0,0 +1,32 @@ +import { describe, it, expect, afterEach } from 'vitest'; +import { cleanup, render } from 'vitest-browser-svelte'; +import PersonCard from './PersonCard.svelte'; + +afterEach(() => cleanup()); + +const PERSON_ID = '55555555-5555-5555-5555-555555555555'; + +const makePerson = (overrides = {}) => ({ + id: PERSON_ID, + firstName: 'Karl', + lastName: 'Raddatz', + displayName: 'Karl Raddatz', + personType: 'PERSON', + ...overrides +}); + +describe('PersonCard add-event affordance (#842)', () => { + it('shows an add-event link pre-seeded with the person to a curator (REQ-003)', () => { + render(PersonCard, { person: makePerson(), canWrite: true }); + const add = document.querySelector( + '[data-testid="person-add-event"]' + ) as HTMLAnchorElement | null; + expect(add).not.toBeNull(); + expect(add?.getAttribute('href')).toBe(`/zeitstrahl/events/new?personId=${PERSON_ID}`); + }); + + it('renders no add-event link to a reader (REQ-004)', () => { + render(PersonCard, { person: makePerson(), canWrite: false }); + expect(document.querySelector('[data-testid="person-add-event"]')).toBeNull(); + }); +});