From d91bedbaaf0ee18498fb2630ebbe83b8c764a5fe Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 11 Jun 2026 13:09:26 +0200 Subject: [PATCH] fix(geschichte): restore focus to item remove button after failed DELETE rollback (#795) Co-Authored-By: Claude Sonnet 4.6 --- .../lib/geschichte/StoryDocumentPanel.svelte | 8 ++++ .../StoryDocumentPanel.svelte.spec.ts | 39 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/frontend/src/lib/geschichte/StoryDocumentPanel.svelte b/frontend/src/lib/geschichte/StoryDocumentPanel.svelte index 9ac55d5d..d1fb448e 100644 --- a/frontend/src/lib/geschichte/StoryDocumentPanel.svelte +++ b/frontend/src/lib/geschichte/StoryDocumentPanel.svelte @@ -102,6 +102,10 @@ async function handleRemove(item: JourneyItemView) { }); if (!res.ok) { items = prev; + await tick(); + sectionEl + ?.querySelector(`[data-item-id="${CSS.escape(item.id)}"] [data-remove-btn]`) + ?.focus(); errorMessage = await failureMessage(res); return; } @@ -109,6 +113,10 @@ async function handleRemove(item: JourneyItemView) { } catch (e) { console.error('Story document remove failed', e); items = prev; + await tick(); + sectionEl + ?.querySelector(`[data-item-id="${CSS.escape(item.id)}"] [data-remove-btn]`) + ?.focus(); errorMessage = m.journey_mutation_error_reload(); } } diff --git a/frontend/src/lib/geschichte/StoryDocumentPanel.svelte.spec.ts b/frontend/src/lib/geschichte/StoryDocumentPanel.svelte.spec.ts index fd5113e4..2aa19803 100644 --- a/frontend/src/lib/geschichte/StoryDocumentPanel.svelte.spec.ts +++ b/frontend/src/lib/geschichte/StoryDocumentPanel.svelte.spec.ts @@ -309,4 +309,43 @@ describe('StoryDocumentPanel — remove', () => { m.geschichte_documents_removed_announce({ title: 'Brief von Eugenie' }) ); }); + + it('returns focus to the item remove button when DELETE fails with !res.ok', async () => { + stubFetch([], { ok: false, status: 500, body: {} }); + render( + StoryDocumentPanel, + defaultProps({ items: [makeItem('i1', 10, docSummary('d1', 'Brief von Eugenie'))] }) + ); + + await userEvent.click( + page.getByRole('button', { + name: m.geschichte_documents_remove_label({ title: 'Brief von Eugenie' }) + }) + ); + + expect(document.activeElement?.getAttribute('aria-label')).toBe( + m.geschichte_documents_remove_label({ title: 'Brief von Eugenie' }) + ); + }); + + it('returns focus to the item remove button when DELETE throws a network error', async () => { + vi.stubGlobal( + 'fetch', + vi.fn(() => Promise.reject(new Error('Network error'))) + ); + render( + StoryDocumentPanel, + defaultProps({ items: [makeItem('i1', 10, docSummary('d1', 'Brief von Eugenie'))] }) + ); + + await userEvent.click( + page.getByRole('button', { + name: m.geschichte_documents_remove_label({ title: 'Brief von Eugenie' }) + }) + ); + + expect(document.activeElement?.getAttribute('aria-label')).toBe( + m.geschichte_documents_remove_label({ title: 'Brief von Eugenie' }) + ); + }); });