diff --git a/frontend/messages/de.json b/frontend/messages/de.json index f5a722a4..9a4a6f0d 100644 --- a/frontend/messages/de.json +++ b/frontend/messages/de.json @@ -815,7 +815,8 @@ "bulk_drop_hint": "Eine oder mehrere Dateien ablegen", "bulk_drop_sub": "PDF, JPEG, PNG oder TIFF · bis zu 50 MB pro Datei", "bulk_count_pill": "{count} werden erstellt", - "bulk_save_cta": "{count, plural, one {Speichern →} other {{count} speichern →}}", + "bulk_save_cta_one": "Speichern →", + "bulk_save_cta": "{count} speichern →", "bulk_discard_all": "Alle verwerfen", "bulk_add_more": "Weitere hinzufügen", "bulk_scope_per_file_label": "Nur diese Datei", diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 9634cb41..0fe3a666 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -815,7 +815,8 @@ "bulk_drop_hint": "Drop one or more files here", "bulk_drop_sub": "PDF, JPEG, PNG or TIFF · up to 50 MB per file", "bulk_count_pill": "{count} will be created", - "bulk_save_cta": "{count, plural, one {Save →} other {Save {count} →}}", + "bulk_save_cta_one": "Save →", + "bulk_save_cta": "Save {count} →", "bulk_discard_all": "Discard all", "bulk_add_more": "Add more", "bulk_scope_per_file_label": "This file only", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 0068a71c..7f086ba1 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -815,7 +815,8 @@ "bulk_drop_hint": "Suelta uno o varios archivos aquí", "bulk_drop_sub": "PDF, JPEG, PNG o TIFF · hasta 50 MB por archivo", "bulk_count_pill": "Se crearán {count}", - "bulk_save_cta": "{count, plural, one {Guardar →} other {Guardar {count} →}}", + "bulk_save_cta_one": "Guardar →", + "bulk_save_cta": "Guardar {count} →", "bulk_discard_all": "Descartar todo", "bulk_add_more": "Añadir más", "bulk_scope_per_file_label": "Solo este archivo", diff --git a/frontend/src/lib/components/document/UploadSaveBar.svelte b/frontend/src/lib/components/document/UploadSaveBar.svelte new file mode 100644 index 00000000..c7e889ef --- /dev/null +++ b/frontend/src/lib/components/document/UploadSaveBar.svelte @@ -0,0 +1,39 @@ + + +
+ {#if chunkProgress} + + {/if} +
+ + +
+
diff --git a/frontend/src/lib/components/document/UploadSaveBar.svelte.spec.ts b/frontend/src/lib/components/document/UploadSaveBar.svelte.spec.ts new file mode 100644 index 00000000..4516a831 --- /dev/null +++ b/frontend/src/lib/components/document/UploadSaveBar.svelte.spec.ts @@ -0,0 +1,48 @@ +import { describe, it, expect, vi, afterEach } from 'vitest'; +import { cleanup, render } from 'vitest-browser-svelte'; +import { page } from 'vitest/browser'; +import UploadSaveBar from './UploadSaveBar.svelte'; + +afterEach(cleanup); + +describe('UploadSaveBar', () => { + it('shows plural label for multiple files', async () => { + render(UploadSaveBar, { fileCount: 5, onSave: vi.fn(), onDiscard: vi.fn() }); + // "5 speichern →" or similar plural form + await expect.element(page.getByText(/5/)).toBeInTheDocument(); + }); + + it('shows singular label for one file', async () => { + render(UploadSaveBar, { fileCount: 1, onSave: vi.fn(), onDiscard: vi.fn() }); + // "Speichern →" singular form + await expect.element(page.getByText(/Speichern/i)).toBeInTheDocument(); + }); + + it('progress bar is visible when chunkProgress is provided', async () => { + const { container } = render(UploadSaveBar, { + fileCount: 3, + chunkProgress: { done: 1, total: 3 }, + onSave: vi.fn(), + onDiscard: vi.fn() + }); + const progress = container.querySelector('progress'); + expect(progress).not.toBeNull(); + expect(progress?.getAttribute('value')).toBe('1'); + expect(progress?.getAttribute('max')).toBe('3'); + }); + + it('progress bar is not rendered when no chunkProgress', async () => { + const { container } = render(UploadSaveBar, { + fileCount: 2, + onSave: vi.fn(), + onDiscard: vi.fn() + }); + const progress = container.querySelector('progress'); + expect(progress).toBeNull(); + }); + + it('discard link is rendered', async () => { + render(UploadSaveBar, { fileCount: 2, onSave: vi.fn(), onDiscard: vi.fn() }); + await expect.element(page.getByText(/verwerfen/i)).toBeInTheDocument(); + }); +});