fix(bulk-upload): spec-compliant split-panel layout with local PDF preview
Rewrites BulkDocumentEditLayout to match the spec exactly: - Fixed viewport layout (same as DocumentEditLayout) filling viewport below nav - Split panel visible in all states (N=0/1/≥2) — was fullscreen dark drop zone - N=0: centered drop-zone-box in left panel; shared form visible but greyed out - N≥1: real PDF preview via URL.createObjectURL (no server upload required) - N≥2: FileSwitcherStrip at bottom of left panel; count pill + discard in topbar - FileEntry gains previewUrl; blob URLs created on add, revoked on remove/destroy - save() checks response.ok and marks failed files with status: 'error' - BulkDropZone redesigned: spec-accurate box with circular mint icon, serif title - FileSwitcherStrip: number badges, arrows, keyboard nav via data-chip-id selector - ScopeCard, UploadSaveBar: hardcoded German replaced with Paraglide i18n keys - +page.svelte simplified to bare component render (layout is self-contained) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ export interface FileEntry {
|
||||
file: File;
|
||||
title: string;
|
||||
status: 'idle' | 'error';
|
||||
previewUrl: string;
|
||||
}
|
||||
|
||||
function makeFiles(n: number): FileEntry[] {
|
||||
@@ -17,7 +18,8 @@ function makeFiles(n: number): FileEntry[] {
|
||||
id: `id-${i}`,
|
||||
file: new File([''], `file${i}.pdf`),
|
||||
title: `File ${i}`,
|
||||
status: 'idle' as const
|
||||
status: 'idle' as const,
|
||||
previewUrl: ''
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -65,7 +67,13 @@ describe('FileSwitcherStrip', () => {
|
||||
|
||||
it('error chip has aria-label containing warning indicator', async () => {
|
||||
const files: FileEntry[] = [
|
||||
{ id: 'e1', file: new File([''], 'bad.pdf'), title: 'Bad file', status: 'error' }
|
||||
{
|
||||
id: 'e1',
|
||||
file: new File([''], 'bad.pdf'),
|
||||
title: 'Bad file',
|
||||
status: 'error',
|
||||
previewUrl: ''
|
||||
}
|
||||
];
|
||||
const { container } = render(FileSwitcherStrip, {
|
||||
files,
|
||||
@@ -85,7 +93,7 @@ describe('FileSwitcherStrip', () => {
|
||||
onSelect: vi.fn(),
|
||||
onRemove: vi.fn()
|
||||
});
|
||||
const firstBtn = container.querySelectorAll('[role="button"]')[0] as HTMLElement;
|
||||
const firstBtn = container.querySelectorAll('[data-chip-id]')[0] as HTMLElement;
|
||||
firstBtn.focus();
|
||||
await userEvent.keyboard('{ArrowRight}');
|
||||
const focused = document.activeElement;
|
||||
|
||||
Reference in New Issue
Block a user