fix(frontend): show error on training start failure, add aria-live and dismiss to success message
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -330,6 +330,7 @@
|
|||||||
"comment_time_days": "vor {count} Tag(en)",
|
"comment_time_days": "vor {count} Tag(en)",
|
||||||
"comment_panel_title": "Kommentare",
|
"comment_panel_title": "Kommentare",
|
||||||
"comment_panel_close": "Schließen",
|
"comment_panel_close": "Schließen",
|
||||||
|
"comp_dismiss": "Schließen",
|
||||||
"doc_panel_tab_metadata": "Metadaten",
|
"doc_panel_tab_metadata": "Metadaten",
|
||||||
"doc_panel_tab_transcription": "Transkription",
|
"doc_panel_tab_transcription": "Transkription",
|
||||||
"doc_panel_tab_discussion": "Diskussion",
|
"doc_panel_tab_discussion": "Diskussion",
|
||||||
@@ -541,6 +542,7 @@
|
|||||||
"training_start_btn": "Training starten",
|
"training_start_btn": "Training starten",
|
||||||
"training_in_progress": "…",
|
"training_in_progress": "…",
|
||||||
"training_success": "Training wurde gestartet und abgeschlossen.",
|
"training_success": "Training wurde gestartet und abgeschlossen.",
|
||||||
|
"training_start_failed": "Training konnte nicht gestartet werden. Bitte versuche es erneut.",
|
||||||
"training_too_few_blocks": "Mindestens 5 geprüfte Blöcke erforderlich (aktuell: {available}).",
|
"training_too_few_blocks": "Mindestens 5 geprüfte Blöcke erforderlich (aktuell: {available}).",
|
||||||
"training_service_down": "OCR-Dienst ist nicht erreichbar.",
|
"training_service_down": "OCR-Dienst ist nicht erreichbar.",
|
||||||
"training_history_heading": "Verlauf",
|
"training_history_heading": "Verlauf",
|
||||||
|
|||||||
@@ -330,6 +330,7 @@
|
|||||||
"comment_time_days": "{count} day(s) ago",
|
"comment_time_days": "{count} day(s) ago",
|
||||||
"comment_panel_title": "Comments",
|
"comment_panel_title": "Comments",
|
||||||
"comment_panel_close": "Close",
|
"comment_panel_close": "Close",
|
||||||
|
"comp_dismiss": "Dismiss",
|
||||||
"doc_panel_tab_metadata": "Metadata",
|
"doc_panel_tab_metadata": "Metadata",
|
||||||
"doc_panel_tab_transcription": "Transcription",
|
"doc_panel_tab_transcription": "Transcription",
|
||||||
"doc_panel_tab_discussion": "Discussion",
|
"doc_panel_tab_discussion": "Discussion",
|
||||||
@@ -541,6 +542,7 @@
|
|||||||
"training_start_btn": "Start training",
|
"training_start_btn": "Start training",
|
||||||
"training_in_progress": "…",
|
"training_in_progress": "…",
|
||||||
"training_success": "Training started and completed.",
|
"training_success": "Training started and completed.",
|
||||||
|
"training_start_failed": "Failed to start training. Please try again.",
|
||||||
"training_too_few_blocks": "At least 5 reviewed blocks required (currently: {available}).",
|
"training_too_few_blocks": "At least 5 reviewed blocks required (currently: {available}).",
|
||||||
"training_service_down": "OCR service is unavailable.",
|
"training_service_down": "OCR service is unavailable.",
|
||||||
"training_history_heading": "History",
|
"training_history_heading": "History",
|
||||||
|
|||||||
@@ -330,6 +330,7 @@
|
|||||||
"comment_time_days": "hace {count} día(s)",
|
"comment_time_days": "hace {count} día(s)",
|
||||||
"comment_panel_title": "Comentarios",
|
"comment_panel_title": "Comentarios",
|
||||||
"comment_panel_close": "Cerrar",
|
"comment_panel_close": "Cerrar",
|
||||||
|
"comp_dismiss": "Cerrar",
|
||||||
"doc_panel_tab_metadata": "Metadatos",
|
"doc_panel_tab_metadata": "Metadatos",
|
||||||
"doc_panel_tab_transcription": "Transcripción",
|
"doc_panel_tab_transcription": "Transcripción",
|
||||||
"doc_panel_tab_discussion": "Discusión",
|
"doc_panel_tab_discussion": "Discusión",
|
||||||
@@ -541,6 +542,7 @@
|
|||||||
"training_start_btn": "Iniciar entrenamiento",
|
"training_start_btn": "Iniciar entrenamiento",
|
||||||
"training_in_progress": "…",
|
"training_in_progress": "…",
|
||||||
"training_success": "Entrenamiento iniciado y completado.",
|
"training_success": "Entrenamiento iniciado y completado.",
|
||||||
|
"training_start_failed": "No se pudo iniciar el entrenamiento. Por favor, inténtalo de nuevo.",
|
||||||
"training_too_few_blocks": "Se requieren al menos 5 bloques revisados (actualmente: {available}).",
|
"training_too_few_blocks": "Se requieren al menos 5 bloques revisados (actualmente: {available}).",
|
||||||
"training_service_down": "El servicio OCR no está disponible.",
|
"training_service_down": "El servicio OCR no está disponible.",
|
||||||
"training_history_heading": "Historial",
|
"training_history_heading": "Historial",
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ let { trainingInfo }: Props = $props();
|
|||||||
|
|
||||||
let training = $state(false);
|
let training = $state(false);
|
||||||
let successMessage = $state<string | null>(null);
|
let successMessage = $state<string | null>(null);
|
||||||
|
let errorMessage = $state<string | null>(null);
|
||||||
|
|
||||||
const available = $derived(trainingInfo?.availableBlocks ?? 0);
|
const available = $derived(trainingInfo?.availableBlocks ?? 0);
|
||||||
const tooFewBlocks = $derived(available < 5);
|
const tooFewBlocks = $derived(available < 5);
|
||||||
@@ -30,6 +31,7 @@ const disabled = $derived(training || tooFewBlocks || serviceDown);
|
|||||||
async function startTraining() {
|
async function startTraining() {
|
||||||
training = true;
|
training = true;
|
||||||
successMessage = null;
|
successMessage = null;
|
||||||
|
errorMessage = null;
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/ocr/train', { method: 'POST' });
|
const res = await fetch('/api/ocr/train', { method: 'POST' });
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
@@ -37,7 +39,11 @@ async function startTraining() {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
successMessage = null;
|
successMessage = null;
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
} else {
|
||||||
|
errorMessage = m.training_start_failed();
|
||||||
}
|
}
|
||||||
|
} catch {
|
||||||
|
errorMessage = m.training_start_failed();
|
||||||
} finally {
|
} finally {
|
||||||
training = false;
|
training = false;
|
||||||
}
|
}
|
||||||
@@ -72,7 +78,19 @@ async function startTraining() {
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if successMessage}
|
{#if successMessage}
|
||||||
<p class="mt-2 text-xs text-green-700">{successMessage}</p>
|
<p class="mt-2 flex items-center gap-2 text-xs text-green-700" aria-live="polite">
|
||||||
|
{successMessage}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="underline hover:no-underline"
|
||||||
|
onclick={() => (successMessage = null)}
|
||||||
|
aria-label={m.comp_dismiss()}>×</button
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if errorMessage}
|
||||||
|
<p class="mt-2 text-xs text-red-600" aria-live="assertive">{errorMessage}</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<h3 class="mt-6 mb-3 text-xs font-bold tracking-widest text-ink-3 uppercase">
|
<h3 class="mt-6 mb-3 text-xs font-bold tracking-widest text-ink-3 uppercase">
|
||||||
|
|||||||
Reference in New Issue
Block a user