feat(persons): add type selector + title + conditional fields to edit form
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,11 @@ import { m } from '$lib/paraglide/messages.js';
|
|||||||
const TYPES = ['PERSON', 'INSTITUTION', 'GROUP', 'UNKNOWN'] as const;
|
const TYPES = ['PERSON', 'INSTITUTION', 'GROUP', 'UNKNOWN'] as const;
|
||||||
type PersonType = (typeof TYPES)[number];
|
type PersonType = (typeof TYPES)[number];
|
||||||
|
|
||||||
let { value = 'PERSON', name = 'personType' }: { value?: string; name?: string } = $props();
|
let {
|
||||||
|
value = 'PERSON',
|
||||||
|
name = 'personType',
|
||||||
|
onchange
|
||||||
|
}: { value?: string; name?: string; onchange?: (type: PersonType) => void } = $props();
|
||||||
|
|
||||||
let selected = $state<PersonType>(
|
let selected = $state<PersonType>(
|
||||||
untrack(() => (TYPES.includes(value as PersonType) ? (value as PersonType) : 'PERSON'))
|
untrack(() => (TYPES.includes(value as PersonType) ? (value as PersonType) : 'PERSON'))
|
||||||
@@ -21,6 +25,7 @@ const labels: Record<PersonType, () => string> = {
|
|||||||
|
|
||||||
function select(type: PersonType) {
|
function select(type: PersonType) {
|
||||||
selected = type;
|
selected = type;
|
||||||
|
onchange?.(type);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { untrack } from 'svelte';
|
||||||
import { m } from '$lib/paraglide/messages.js';
|
import { m } from '$lib/paraglide/messages.js';
|
||||||
|
import PersonTypeSelector from '$lib/components/PersonTypeSelector.svelte';
|
||||||
|
|
||||||
|
type PersonType = 'PERSON' | 'INSTITUTION' | 'GROUP' | 'UNKNOWN';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
person
|
person
|
||||||
}: {
|
}: {
|
||||||
person: {
|
person: {
|
||||||
|
personType?: string | null;
|
||||||
|
title?: string | null;
|
||||||
firstName?: string | null;
|
firstName?: string | null;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
alias?: string | null;
|
alias?: string | null;
|
||||||
@@ -13,25 +19,68 @@ let {
|
|||||||
notes?: string | null;
|
notes?: string | null;
|
||||||
};
|
};
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
|
const TYPES = ['PERSON', 'INSTITUTION', 'GROUP', 'UNKNOWN'] as const;
|
||||||
|
let selectedType = $state<PersonType>(
|
||||||
|
untrack(() =>
|
||||||
|
TYPES.includes(person.personType as PersonType) ? (person.personType as PersonType) : 'PERSON'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const isPerson = $derived(selectedType === 'PERSON');
|
||||||
|
const lastNameLabel = $derived(
|
||||||
|
selectedType === 'INSTITUTION' || selectedType === 'GROUP'
|
||||||
|
? m.form_label_name()
|
||||||
|
: m.form_label_last_name()
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
<div>
|
<div class="md:col-span-2">
|
||||||
<label for="firstName" class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
<p class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase">
|
||||||
>{m.form_label_first_name()} *</label
|
{m.form_label_person_type()}
|
||||||
>
|
</p>
|
||||||
<input
|
<PersonTypeSelector
|
||||||
id="firstName"
|
value={selectedType}
|
||||||
name="firstName"
|
name="personType"
|
||||||
type="text"
|
onchange={(type: PersonType) => (selectedType = type)}
|
||||||
required
|
|
||||||
value={person.firstName}
|
|
||||||
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
|
{#if isPerson}
|
||||||
|
<div>
|
||||||
|
<label for="title" class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
||||||
|
>{m.form_label_title()}</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="title"
|
||||||
|
name="title"
|
||||||
|
type="text"
|
||||||
|
maxlength="50"
|
||||||
|
value={person.title ?? ''}
|
||||||
|
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
for="firstName"
|
||||||
|
class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
||||||
|
>{m.form_label_first_name()} *</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="firstName"
|
||||||
|
name="firstName"
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
value={person.firstName ?? ''}
|
||||||
|
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class={!isPerson ? 'md:col-span-2' : ''}>
|
||||||
<label for="lastName" class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
<label for="lastName" class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
||||||
>{m.form_label_last_name()} *</label
|
>{lastNameLabel} *</label
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
id="lastName"
|
id="lastName"
|
||||||
@@ -42,48 +91,56 @@ let {
|
|||||||
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="md:col-span-2">
|
|
||||||
<label for="alias" class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
{#if isPerson}
|
||||||
>{m.form_label_alias()}</label
|
<div class="md:col-span-2">
|
||||||
>
|
<label for="alias" class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
||||||
<input
|
>{m.form_label_alias()}</label
|
||||||
id="alias"
|
>
|
||||||
name="alias"
|
<input
|
||||||
type="text"
|
id="alias"
|
||||||
value={person.alias ?? ''}
|
name="alias"
|
||||||
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
type="text"
|
||||||
/>
|
value={person.alias ?? ''}
|
||||||
</div>
|
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
<div>
|
/>
|
||||||
<label for="birthYear" class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
</div>
|
||||||
>{m.person_label_birth_year()}</label
|
<div>
|
||||||
>
|
<label
|
||||||
<input
|
for="birthYear"
|
||||||
id="birthYear"
|
class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
||||||
name="birthYear"
|
>{m.person_label_birth_year()}</label
|
||||||
type="number"
|
>
|
||||||
min="1"
|
<input
|
||||||
max="2100"
|
id="birthYear"
|
||||||
placeholder={m.person_placeholder_year()}
|
name="birthYear"
|
||||||
value={person.birthYear ?? ''}
|
type="number"
|
||||||
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
min="1"
|
||||||
/>
|
max="2100"
|
||||||
</div>
|
placeholder={m.person_placeholder_year()}
|
||||||
<div>
|
value={person.birthYear ?? ''}
|
||||||
<label for="deathYear" class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
>{m.person_label_death_year()}</label
|
/>
|
||||||
>
|
</div>
|
||||||
<input
|
<div>
|
||||||
id="deathYear"
|
<label
|
||||||
name="deathYear"
|
for="deathYear"
|
||||||
type="number"
|
class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
||||||
min="1"
|
>{m.person_label_death_year()}</label
|
||||||
max="2100"
|
>
|
||||||
placeholder={m.person_placeholder_year()}
|
<input
|
||||||
value={person.deathYear ?? ''}
|
id="deathYear"
|
||||||
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
name="deathYear"
|
||||||
/>
|
type="number"
|
||||||
</div>
|
min="1"
|
||||||
|
max="2100"
|
||||||
|
placeholder={m.person_placeholder_year()}
|
||||||
|
value={person.deathYear ?? ''}
|
||||||
|
class="block w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<div class="md:col-span-2">
|
<div class="md:col-span-2">
|
||||||
<label for="notes" class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
<label for="notes" class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase"
|
||||||
>{m.person_label_notes()}</label
|
>{m.person_label_notes()}</label
|
||||||
|
|||||||
Reference in New Issue
Block a user