feat(bulk-upload): guard discard-all with confirm dialog

Uses getConfirmService() (optional — null fallback when context is absent so
unit tests that don't exercise the discard path need no CONFIRM_KEY context)
and the new bulk_discard_confirm i18n key.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-25 11:26:05 +02:00
parent e5fe2fc5c6
commit 46dae8a826
4 changed files with 27 additions and 2 deletions

View File

@@ -858,6 +858,7 @@
"bulk_save_cta_one": "Speichern →",
"bulk_save_cta": "{count} speichern →",
"bulk_discard_all": "Alle verwerfen",
"bulk_discard_confirm": "Alle Dateien und eingegebenen Daten verwerfen? Diese Aktion kann nicht rückgängig gemacht werden.",
"bulk_add_more": "Weitere hinzufügen",
"bulk_scope_per_file_label": "Nur diese Datei",
"bulk_scope_shared_label": "Gilt für alle {count}",

View File

@@ -858,6 +858,7 @@
"bulk_save_cta_one": "Save →",
"bulk_save_cta": "Save {count} →",
"bulk_discard_all": "Discard all",
"bulk_discard_confirm": "Discard all files and entered data? This action cannot be undone.",
"bulk_add_more": "Add more",
"bulk_scope_per_file_label": "This file only",
"bulk_scope_shared_label": "Applies to all {count}",

View File

@@ -858,6 +858,7 @@
"bulk_save_cta_one": "Guardar →",
"bulk_save_cta": "Guardar {count} →",
"bulk_discard_all": "Descartar todo",
"bulk_discard_confirm": "¿Descartar todos los archivos y datos introducidos? Esta acción no se puede deshacer.",
"bulk_add_more": "Añadir más",
"bulk_scope_per_file_label": "Solo este archivo",
"bulk_scope_shared_label": "Para todos los {count}",

View File

@@ -3,6 +3,8 @@ import { SvelteMap } from 'svelte/reactivity';
import { goto } from '$app/navigation';
import { onDestroy, untrack } from 'svelte';
import { m } from '$lib/paraglide/messages.js';
import { getConfirmService } from '$lib/services/confirm.svelte.js';
import type { ConfirmService } from '$lib/services/confirm.svelte.js';
import BulkDropZone from './BulkDropZone.svelte';
import FileSwitcherStrip from './FileSwitcherStrip.svelte';
import type { FileEntry } from './FileSwitcherStrip.svelte';
@@ -17,6 +19,14 @@ import type { components } from '$lib/generated/api';
type Person = components['schemas']['Person'];
// Optional — not available in unit tests that don't provide CONFIRM_KEY context.
let _confirmService: ConfirmService | null;
try {
_confirmService = getConfirmService();
} catch {
_confirmService = null;
}
let {
initialSenderId = '',
initialSenderName = '',
@@ -77,6 +87,18 @@ function discardAll() {
chunkProgress = undefined;
}
async function handleDiscard() {
if (_confirmService) {
const ok = await _confirmService.confirm({
title: m.bulk_discard_all(),
body: m.bulk_discard_confirm(),
destructive: true
});
if (!ok) return;
}
discardAll();
}
onDestroy(() => {
for (const entry of files.values()) {
if (entry.previewUrl) URL.revokeObjectURL(entry.previewUrl);
@@ -177,7 +199,7 @@ async function save() {
<button
type="button"
data-testid="discard-all-btn"
onclick={discardAll}
onclick={handleDiscard}
class="text-xs font-medium text-red-600/70 hover:text-red-700"
>
{m.bulk_discard_all()}
@@ -289,7 +311,7 @@ async function save() {
fileCount={files.size}
chunkProgress={chunkProgress}
onSave={save}
onDiscard={discardAll}
onDiscard={handleDiscard}
disabled={saving}
/>
</div>