feat(frontend): show OcrProgress during OCR job + check status on load
Some checks failed
CI / Unit & Component Tests (push) Failing after 1s
CI / Backend Unit Tests (push) Failing after 2s
CI / Unit & Component Tests (pull_request) Failing after 1s
CI / Backend Unit Tests (pull_request) Failing after 1s

- triggerOcr captures jobId from POST response and shows OcrProgress
- OcrProgress rendered in the transcription panel when ocrJobId is set
- handleOcrDone reloads blocks and annotations when OCR completes
- checkOcrStatus called when entering transcription mode — resumes
  progress display if a job is already running for this document

Refs #226

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-12 22:09:24 +02:00
parent 8dc9243add
commit f6667e0e15

View File

@@ -6,6 +6,7 @@ import DocumentViewer from '$lib/components/DocumentViewer.svelte';
import TranscriptionEditView from '$lib/components/TranscriptionEditView.svelte'; import TranscriptionEditView from '$lib/components/TranscriptionEditView.svelte';
import TranscriptionReadView from '$lib/components/TranscriptionReadView.svelte'; import TranscriptionReadView from '$lib/components/TranscriptionReadView.svelte';
import TranscriptionPanelHeader from '$lib/components/TranscriptionPanelHeader.svelte'; import TranscriptionPanelHeader from '$lib/components/TranscriptionPanelHeader.svelte';
import OcrProgress from '$lib/components/OcrProgress.svelte';
import type { TranscriptionBlockData } from '$lib/types'; import type { TranscriptionBlockData } from '$lib/types';
let { data } = $props(); let { data } = $props();
@@ -57,6 +58,7 @@ let activeAnnotationId = $state<string | null>(null);
let highlightBlockId = $state<string | null>(null); let highlightBlockId = $state<string | null>(null);
let flashAnnotationId = $state<string | null>(null); let flashAnnotationId = $state<string | null>(null);
let pdfStripExpanded = $state(false); let pdfStripExpanded = $state(false);
let ocrJobId = $state<string | null>(null);
const prefersReducedMotion = $derived( const prefersReducedMotion = $derived(
typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches
@@ -135,14 +137,21 @@ async function triggerOcr(scriptType: string) {
body: JSON.stringify({ scriptType }) body: JSON.stringify({ scriptType })
}); });
if (res.ok) { if (res.ok) {
await loadTranscriptionBlocks(); const data = await res.json();
annotationReloadKey++; ocrJobId = data.jobId;
} }
} catch (e) { } catch (e) {
console.error('Failed to trigger OCR:', e); console.error('Failed to trigger OCR:', e);
} }
} }
async function handleOcrDone() {
ocrJobId = null;
await loadTranscriptionBlocks();
annotationReloadKey++;
panelMode = transcriptionBlocks.length > 0 ? 'read' : 'edit';
}
async function createBlockFromDraw(rect: { async function createBlockFromDraw(rect: {
x: number; x: number;
y: number; y: number;
@@ -223,12 +232,28 @@ function handleParagraphClick(annotationId: string) {
); );
} }
// Load blocks when transcribe mode is entered and set default panel mode async function checkOcrStatus() {
if (!doc?.id) return;
try {
const res = await fetch(`/api/documents/${doc.id}/ocr-status`);
if (res.ok) {
const status = await res.json();
if (status.status === 'PENDING' || status.status === 'RUNNING') {
ocrJobId = status.jobId;
}
}
} catch {
// OCR status check is best-effort
}
}
// Load blocks and check OCR status when transcribe mode is entered
$effect(() => { $effect(() => {
if (transcribeMode) { if (transcribeMode) {
loadTranscriptionBlocks().then(() => { loadTranscriptionBlocks().then(() => {
panelMode = transcriptionBlocks.length > 0 ? 'read' : 'edit'; panelMode = transcriptionBlocks.length > 0 ? 'read' : 'edit';
}); });
checkOcrStatus();
} }
}); });
@@ -328,7 +353,11 @@ onMount(() => {
onClose={() => (transcribeMode = false)} onClose={() => (transcribeMode = false)}
/> />
<div class="flex-1 overflow-y-auto"> <div class="flex-1 overflow-y-auto">
{#if panelMode === 'read'} {#if ocrJobId}
<div class="p-4">
<OcrProgress jobId={ocrJobId} onDone={handleOcrDone} />
</div>
{:else if panelMode === 'read'}
<TranscriptionReadView <TranscriptionReadView
blocks={transcriptionBlocks} blocks={transcriptionBlocks}
highlightBlockId={highlightBlockId} highlightBlockId={highlightBlockId}