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:
@@ -858,6 +858,7 @@
|
|||||||
"bulk_save_cta_one": "Speichern →",
|
"bulk_save_cta_one": "Speichern →",
|
||||||
"bulk_save_cta": "{count} speichern →",
|
"bulk_save_cta": "{count} speichern →",
|
||||||
"bulk_discard_all": "Alle verwerfen",
|
"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_add_more": "Weitere hinzufügen",
|
||||||
"bulk_scope_per_file_label": "Nur diese Datei",
|
"bulk_scope_per_file_label": "Nur diese Datei",
|
||||||
"bulk_scope_shared_label": "Gilt für alle {count}",
|
"bulk_scope_shared_label": "Gilt für alle {count}",
|
||||||
|
|||||||
@@ -858,6 +858,7 @@
|
|||||||
"bulk_save_cta_one": "Save →",
|
"bulk_save_cta_one": "Save →",
|
||||||
"bulk_save_cta": "Save {count} →",
|
"bulk_save_cta": "Save {count} →",
|
||||||
"bulk_discard_all": "Discard all",
|
"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_add_more": "Add more",
|
||||||
"bulk_scope_per_file_label": "This file only",
|
"bulk_scope_per_file_label": "This file only",
|
||||||
"bulk_scope_shared_label": "Applies to all {count}",
|
"bulk_scope_shared_label": "Applies to all {count}",
|
||||||
|
|||||||
@@ -858,6 +858,7 @@
|
|||||||
"bulk_save_cta_one": "Guardar →",
|
"bulk_save_cta_one": "Guardar →",
|
||||||
"bulk_save_cta": "Guardar {count} →",
|
"bulk_save_cta": "Guardar {count} →",
|
||||||
"bulk_discard_all": "Descartar todo",
|
"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_add_more": "Añadir más",
|
||||||
"bulk_scope_per_file_label": "Solo este archivo",
|
"bulk_scope_per_file_label": "Solo este archivo",
|
||||||
"bulk_scope_shared_label": "Para todos los {count}",
|
"bulk_scope_shared_label": "Para todos los {count}",
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { SvelteMap } from 'svelte/reactivity';
|
|||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { onDestroy, untrack } from 'svelte';
|
import { onDestroy, untrack } from 'svelte';
|
||||||
import { m } from '$lib/paraglide/messages.js';
|
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 BulkDropZone from './BulkDropZone.svelte';
|
||||||
import FileSwitcherStrip from './FileSwitcherStrip.svelte';
|
import FileSwitcherStrip from './FileSwitcherStrip.svelte';
|
||||||
import type { FileEntry } 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'];
|
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 {
|
let {
|
||||||
initialSenderId = '',
|
initialSenderId = '',
|
||||||
initialSenderName = '',
|
initialSenderName = '',
|
||||||
@@ -77,6 +87,18 @@ function discardAll() {
|
|||||||
chunkProgress = undefined;
|
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(() => {
|
onDestroy(() => {
|
||||||
for (const entry of files.values()) {
|
for (const entry of files.values()) {
|
||||||
if (entry.previewUrl) URL.revokeObjectURL(entry.previewUrl);
|
if (entry.previewUrl) URL.revokeObjectURL(entry.previewUrl);
|
||||||
@@ -177,7 +199,7 @@ async function save() {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
data-testid="discard-all-btn"
|
data-testid="discard-all-btn"
|
||||||
onclick={discardAll}
|
onclick={handleDiscard}
|
||||||
class="text-xs font-medium text-red-600/70 hover:text-red-700"
|
class="text-xs font-medium text-red-600/70 hover:text-red-700"
|
||||||
>
|
>
|
||||||
{m.bulk_discard_all()}
|
{m.bulk_discard_all()}
|
||||||
@@ -289,7 +311,7 @@ async function save() {
|
|||||||
fileCount={files.size}
|
fileCount={files.size}
|
||||||
chunkProgress={chunkProgress}
|
chunkProgress={chunkProgress}
|
||||||
onSave={save}
|
onSave={save}
|
||||||
onDiscard={discardAll}
|
onDiscard={handleDiscard}
|
||||||
disabled={saving}
|
disabled={saving}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user