Some checks failed
CI / Unit & Component Tests (push) Failing after 3m2s
CI / OCR Service Tests (push) Successful in 33s
CI / Backend Unit Tests (push) Failing after 2m56s
CI / Unit & Component Tests (pull_request) Failing after 3m3s
CI / OCR Service Tests (pull_request) Successful in 31s
CI / Backend Unit Tests (pull_request) Failing after 2m56s
Closes #342. The PersonDangerZone collapsible wrapper is removed; PersonMergePanel is now rendered directly in the edit page with its own red border (border-red-200), preserving the {#key person.id} state-reset behaviour and the two-step merge flow. Fix PersonTypeahead mock to use Svelte 5 functional stub (not Svelte 3/4 $$ internals). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
84 lines
2.5 KiB
Svelte
84 lines
2.5 KiB
Svelte
<script lang="ts">
|
|
import { enhance } from '$app/forms';
|
|
import PersonTypeahead from '$lib/components/PersonTypeahead.svelte';
|
|
import { m } from '$lib/paraglide/messages.js';
|
|
|
|
let {
|
|
person,
|
|
form
|
|
}: {
|
|
person: { displayName: string };
|
|
form?: { mergeError?: string } | null;
|
|
} = $props();
|
|
|
|
let mergeTargetId = $state('');
|
|
let showMergeConfirm = $state(false);
|
|
</script>
|
|
|
|
<div class="mb-10 overflow-hidden rounded-sm border border-red-200 bg-surface shadow-sm">
|
|
<div class="p-6 md:p-8">
|
|
<h2 class="mb-1 font-serif text-lg text-ink">{m.person_merge_heading()}</h2>
|
|
<p class="mb-5 font-sans text-sm text-ink-2">
|
|
{m.person_merge_description()}
|
|
</p>
|
|
|
|
{#if form?.mergeError}
|
|
<p class="mb-4 rounded border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-600">
|
|
{form.mergeError}
|
|
</p>
|
|
{/if}
|
|
|
|
<form method="POST" action="?/merge" use:enhance>
|
|
<input type="hidden" name="targetPersonId" bind:value={mergeTargetId} />
|
|
|
|
<div class="flex flex-col items-end gap-3 sm:flex-row">
|
|
<div class="flex-1">
|
|
<PersonTypeahead
|
|
name="_targetPersonDisplay"
|
|
label={m.person_merge_target_label()}
|
|
value={mergeTargetId}
|
|
onchange={(value) => {
|
|
mergeTargetId = value;
|
|
showMergeConfirm = false;
|
|
}}
|
|
/>
|
|
</div>
|
|
|
|
{#if !showMergeConfirm}
|
|
<button
|
|
type="button"
|
|
disabled={!mergeTargetId}
|
|
onclick={() => (showMergeConfirm = true)}
|
|
class="rounded border border-red-300 px-4 py-2 text-sm font-bold tracking-widest text-red-600 uppercase transition-colors hover:bg-red-50 disabled:cursor-not-allowed disabled:opacity-40"
|
|
>
|
|
{m.person_btn_merge()}
|
|
</button>
|
|
{:else}
|
|
<div class="flex gap-2">
|
|
<button
|
|
type="submit"
|
|
class="rounded bg-red-600 px-4 py-2 text-sm font-bold tracking-widest text-white uppercase transition-colors hover:bg-red-700"
|
|
>
|
|
{m.person_btn_merge_confirm()}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
onclick={() => (showMergeConfirm = false)}
|
|
class="rounded border border-line px-4 py-2 text-sm font-bold tracking-widest text-ink-2 uppercase transition-colors hover:bg-muted"
|
|
>
|
|
{m.btn_cancel()}
|
|
</button>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
|
|
{#if showMergeConfirm}
|
|
<p class="mt-3 rounded border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
|
|
{m.person_merge_warning()} <strong>{person.displayName}</strong>
|
|
{m.person_merge_will_be_deleted()}
|
|
</p>
|
|
{/if}
|
|
</form>
|
|
</div>
|
|
</div>
|