fix(chronik): surface action failures in ChronikFuerDichBox with accessible error banner
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 3m35s
CI / OCR Service Tests (pull_request) Successful in 20s
CI / Backend Unit Tests (pull_request) Successful in 3m17s
CI / fail2ban Regex (pull_request) Successful in 41s
CI / Semgrep Security Scan (pull_request) Successful in 20s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m1s

Add $state errorMessage + role=alert banner to ChronikFuerDichBox. Both enhance callbacks
now inspect result.type and set the error message on 'failure' or 'error'; errorMessage
is cleared on each new submit attempt.

Upgrade both test files to the mockFormResult pattern (via vi.hoisted) so the result
callback is exercised. Add a failing-action test in each file that asserts role=alert
appears after a form submit with type='failure'.

Fix bare Function cast → explicit typed cast to satisfy @typescript-eslint/no-unsafe-function-type.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-20 07:06:58 +02:00
parent 2adb98895d
commit f2bb58e294
3 changed files with 97 additions and 10 deletions

View File

@@ -13,6 +13,8 @@ interface Props {
const { unread, optimisticMarkRead, optimisticMarkAllRead }: Props = $props();
let errorMessage: string | null = $state(null);
function verb(type: NotificationItem['type'], actor: string): string {
return type === 'REPLY'
? m.notification_type_reply({ actor })
@@ -25,6 +27,9 @@ function href(n: NotificationItem): string {
</script>
<section class="rounded-sm border border-line bg-surface p-5">
{#if errorMessage}
<p role="alert" class="px-4 py-2 text-sm text-red-600">{errorMessage}</p>
{/if}
{#if unread.length === 0}
<div data-testid="chronik-inbox-zero" class="flex flex-col items-center gap-3 py-6 text-center">
<svg
@@ -71,8 +76,12 @@ function href(n: NotificationItem): string {
action="/aktivitaeten?/mark-all-read"
method="POST"
use:enhance={() => {
errorMessage = null;
optimisticMarkAllRead();
return async ({ update }) => {
return async ({ result, update }) => {
if (result.type === 'failure' || result.type === 'error') {
errorMessage = m.notification_error_generic();
}
await update({ reset: false, invalidateAll: false });
};
}}
@@ -115,8 +124,12 @@ function href(n: NotificationItem): string {
action="/aktivitaeten?/dismiss-notification"
method="POST"
use:enhance={() => {
errorMessage = null;
optimisticMarkRead(n.id);
return async ({ update }) => {
return async ({ result, update }) => {
if (result.type === 'failure' || result.type === 'error') {
errorMessage = m.notification_error_generic();
}
await update({ reset: false, invalidateAll: false });
};
}}