Restructure the "New Document" page so users can save quickly: - FileSectionNew becomes the first element, redesigned as a prominent upload zone with an icon and large click target - Title field is rendered standalone below the upload zone; it auto-populates from the filename (via parseFilename + stripExtension fallback) unless the user has already typed something - All remaining metadata (who/when, description, transcription) moves into a collapsible "Weitere Details" section that auto-expands when URL prefill data or a form error is present, or when filename parsing detects a date/person - title is no longer required — the form can be saved with only a file - DescriptionSection gains a `hideTitle` prop for use in this layout - `form_label_title` translation key no longer carries a hardcoded `*`; the asterisk is rendered by the template only when `titleRequired` is set (currently only the edit form) - E2E tests added for all three scenarios from the issue Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
96 lines
2.6 KiB
Svelte
96 lines
2.6 KiB
Svelte
<script lang="ts">
|
|
import { untrack } from 'svelte';
|
|
import TagInput from '$lib/components/TagInput.svelte';
|
|
import { m } from '$lib/paraglide/messages.js';
|
|
|
|
let {
|
|
tags = $bindable<string[]>([]),
|
|
initialTitle = '',
|
|
initialDocumentLocation = '',
|
|
initialSummary = '',
|
|
titleRequired = false,
|
|
suggestedTitle = '',
|
|
hideTitle = false
|
|
}: {
|
|
tags?: string[];
|
|
initialTitle?: string;
|
|
initialDocumentLocation?: string;
|
|
initialSummary?: string;
|
|
titleRequired?: boolean;
|
|
suggestedTitle?: string;
|
|
hideTitle?: boolean;
|
|
} = $props();
|
|
|
|
let titleDirty = $state(false);
|
|
let titleOverride = $state(untrack(() => initialTitle));
|
|
let titleValue = $derived(titleDirty ? titleOverride : suggestedTitle || titleOverride);
|
|
</script>
|
|
|
|
<div class="rounded-sm border border-line bg-surface p-6 shadow-sm">
|
|
<h2 class="mb-5 text-xs font-bold tracking-widest text-ink-3 uppercase">
|
|
{m.doc_section_description()}
|
|
</h2>
|
|
|
|
<div class="space-y-5">
|
|
{#if !hideTitle}
|
|
<!-- Titel -->
|
|
<div>
|
|
<label for="title" class="mb-1 block text-sm font-medium text-ink-2"
|
|
>{m.form_label_title()}{#if titleRequired}
|
|
*{/if}</label
|
|
>
|
|
<input
|
|
id="title"
|
|
type="text"
|
|
name="title"
|
|
value={titleValue}
|
|
oninput={(e) => {
|
|
titleOverride = (e.target as HTMLInputElement).value;
|
|
titleDirty = true;
|
|
}}
|
|
required={titleRequired}
|
|
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
|
/>
|
|
</div>
|
|
{/if}
|
|
|
|
<!-- Aufbewahrungsort -->
|
|
<div>
|
|
<label for="documentLocation" class="mb-1 block text-sm font-medium text-ink-2"
|
|
>{m.form_label_archive_location()}</label
|
|
>
|
|
<input
|
|
id="documentLocation"
|
|
type="text"
|
|
name="documentLocation"
|
|
value={initialDocumentLocation}
|
|
placeholder={m.form_placeholder_archive_location()}
|
|
class="block w-full rounded border border-line p-2 text-sm shadow-sm focus:border-ink focus:ring-ink"
|
|
/>
|
|
<p class="mt-1 text-xs text-ink-3">{m.form_helper_archive_location()}</p>
|
|
</div>
|
|
|
|
<!-- Schlagworte -->
|
|
<div>
|
|
<p class="mb-1 block text-sm font-medium text-ink-2">{m.form_label_tags()}</p>
|
|
<TagInput bind:tags={tags} />
|
|
<input type="hidden" name="tags" value={tags.join(',')} />
|
|
</div>
|
|
|
|
<!-- Inhalt -->
|
|
<div>
|
|
<label for="summary" class="mb-1 block text-sm font-medium text-ink-2"
|
|
>{m.form_label_content()}</label
|
|
>
|
|
<textarea
|
|
id="summary"
|
|
name="summary"
|
|
rows="5"
|
|
placeholder={m.form_placeholder_content()}
|
|
class="block w-full rounded border border-line p-2 font-serif text-sm shadow-sm focus:border-ink focus:ring-ink"
|
|
>{initialSummary}</textarea
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|