From c94d2cec0312cdea23b4859f13aab28475455450 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sat, 25 Apr 2026 11:26:05 +0200 Subject: [PATCH] feat(bulk-upload): guard discard-all with confirm dialog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- frontend/messages/de.json | 1 + frontend/messages/en.json | 1 + frontend/messages/es.json | 1 + .../document/BulkDocumentEditLayout.svelte | 26 +++++++++++++++++-- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/frontend/messages/de.json b/frontend/messages/de.json index 28dbd9cd..877d3791 100644 --- a/frontend/messages/de.json +++ b/frontend/messages/de.json @@ -857,6 +857,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}", diff --git a/frontend/messages/en.json b/frontend/messages/en.json index b173ecdd..0ffc9105 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -857,6 +857,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}", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 56c3f41a..9b5683f9 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -857,6 +857,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}", diff --git a/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte b/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte index 7733924a..bc76ff5b 100644 --- a/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte +++ b/frontend/src/lib/components/document/BulkDocumentEditLayout.svelte @@ -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() {