fix(ocr-pipeline): show sub-columns in reconstruction and LLM review steps
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 27s
CI / test-go-edu-search (push) Successful in 26s
CI / test-python-klausur (push) Failing after 1m54s
CI / test-python-agent-core (push) Successful in 18s
CI / test-nodejs-website (push) Successful in 21s
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 27s
CI / test-go-edu-search (push) Successful in 26s
CI / test-python-klausur (push) Failing after 1m54s
CI / test-python-agent-core (push) Successful in 18s
CI / test-nodejs-website (push) Successful in 21s
- Add marker/bbox_marker fields to WordEntry type - Add page_ref/column_marker colors to StepReconstruction - Make StepLlmReview table dynamic based on columns_used metadata, showing all detected columns (EN, DE, Example, page_ref, marker) instead of hardcoded EN/DE/Beispiel only Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -181,12 +181,14 @@ export interface WordEntry {
|
||||
german: string
|
||||
example: string
|
||||
source_page?: string
|
||||
marker?: string
|
||||
confidence: number
|
||||
bbox: WordBbox
|
||||
bbox_en: WordBbox | null
|
||||
bbox_de: WordBbox | null
|
||||
bbox_ex: WordBbox | null
|
||||
bbox_ref?: WordBbox | null
|
||||
bbox_marker?: WordBbox | null
|
||||
status?: 'pending' | 'confirmed' | 'edited' | 'skipped'
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import type { GridResult, WordEntry } from '@/app/(admin)/ai/ocr-pipeline/types'
|
||||
import type { GridResult, WordEntry, ColumnMeta } from '@/app/(admin)/ai/ocr-pipeline/types'
|
||||
|
||||
const KLAUSUR_API = '/klausur-api'
|
||||
|
||||
@@ -34,6 +34,26 @@ const FIELD_LABELS: Record<string, string> = {
|
||||
english: 'EN',
|
||||
german: 'DE',
|
||||
example: 'Beispiel',
|
||||
source_page: 'Seite',
|
||||
marker: 'Marker',
|
||||
}
|
||||
|
||||
/** Map column type to WordEntry field name */
|
||||
const COL_TYPE_TO_FIELD: Record<string, string> = {
|
||||
column_en: 'english',
|
||||
column_de: 'german',
|
||||
column_example: 'example',
|
||||
page_ref: 'source_page',
|
||||
column_marker: 'marker',
|
||||
}
|
||||
|
||||
/** Column type → color class */
|
||||
const COL_TYPE_COLOR: Record<string, string> = {
|
||||
column_en: 'text-blue-600 dark:text-blue-400',
|
||||
column_de: 'text-green-600 dark:text-green-400',
|
||||
column_example: 'text-orange-600 dark:text-orange-400',
|
||||
page_ref: 'text-cyan-600 dark:text-cyan-400',
|
||||
column_marker: 'text-gray-500 dark:text-gray-400',
|
||||
}
|
||||
|
||||
type RowStatus = 'pending' | 'active' | 'reviewed' | 'corrected' | 'skipped'
|
||||
@@ -51,6 +71,7 @@ export function StepLlmReview({ sessionId, onNext }: StepLlmReviewProps) {
|
||||
|
||||
// Full vocab table state
|
||||
const [vocabEntries, setVocabEntries] = useState<WordEntry[]>([])
|
||||
const [columnsUsed, setColumnsUsed] = useState<ColumnMeta[]>([])
|
||||
const [activeRowIndices, setActiveRowIndices] = useState<Set<number>>(new Set())
|
||||
const [reviewedRows, setReviewedRows] = useState<Set<number>>(new Set())
|
||||
const [skippedRows, setSkippedRows] = useState<Set<number>>(new Set())
|
||||
@@ -86,6 +107,7 @@ export function StepLlmReview({ sessionId, onNext }: StepLlmReviewProps) {
|
||||
|
||||
const entries = wordResult.vocab_entries || wordResult.entries || []
|
||||
setVocabEntries(entries)
|
||||
setColumnsUsed(wordResult.columns_used || [])
|
||||
|
||||
// Check if LLM review was already run
|
||||
const llmReview = wordResult.llm_review
|
||||
@@ -458,9 +480,23 @@ export function StepLlmReview({ sessionId, onNext }: StepLlmReviewProps) {
|
||||
<thead className="sticky top-0 z-10">
|
||||
<tr className="bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
|
||||
<th className="px-2 py-2 text-left text-gray-500 dark:text-gray-400 font-medium w-10">#</th>
|
||||
<th className="px-2 py-2 text-left text-gray-500 dark:text-gray-400 font-medium">EN</th>
|
||||
<th className="px-2 py-2 text-left text-gray-500 dark:text-gray-400 font-medium">DE</th>
|
||||
<th className="px-2 py-2 text-left text-gray-500 dark:text-gray-400 font-medium">Beispiel</th>
|
||||
{columnsUsed.length > 0 ? (
|
||||
columnsUsed.map((col, i) => {
|
||||
const field = COL_TYPE_TO_FIELD[col.type]
|
||||
if (!field) return null
|
||||
return (
|
||||
<th key={i} className={`px-2 py-2 text-left font-medium ${COL_TYPE_COLOR[col.type] || 'text-gray-500 dark:text-gray-400'}`}>
|
||||
{FIELD_LABELS[field] || field}
|
||||
</th>
|
||||
)
|
||||
})
|
||||
) : (
|
||||
<>
|
||||
<th className="px-2 py-2 text-left text-gray-500 dark:text-gray-400 font-medium">EN</th>
|
||||
<th className="px-2 py-2 text-left text-gray-500 dark:text-gray-400 font-medium">DE</th>
|
||||
<th className="px-2 py-2 text-left text-gray-500 dark:text-gray-400 font-medium">Beispiel</th>
|
||||
</>
|
||||
)}
|
||||
<th className="px-2 py-2 text-center text-gray-500 dark:text-gray-400 font-medium w-16">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -486,15 +522,30 @@ export function StepLlmReview({ sessionId, onNext }: StepLlmReviewProps) {
|
||||
}`}
|
||||
>
|
||||
<td className="px-2 py-1.5 text-gray-400 font-mono text-xs">{idx}</td>
|
||||
<td className="px-2 py-1.5">
|
||||
<CellContent text={entry.english} field="english" rowChanges={rowChanges} />
|
||||
</td>
|
||||
<td className="px-2 py-1.5">
|
||||
<CellContent text={entry.german} field="german" rowChanges={rowChanges} />
|
||||
</td>
|
||||
<td className="px-2 py-1.5 text-xs">
|
||||
<CellContent text={entry.example} field="example" rowChanges={rowChanges} />
|
||||
</td>
|
||||
{columnsUsed.length > 0 ? (
|
||||
columnsUsed.map((col, i) => {
|
||||
const field = COL_TYPE_TO_FIELD[col.type]
|
||||
if (!field) return null
|
||||
const text = (entry as Record<string, unknown>)[field] as string || ''
|
||||
return (
|
||||
<td key={i} className="px-2 py-1.5 text-xs">
|
||||
<CellContent text={text} field={field} rowChanges={rowChanges} />
|
||||
</td>
|
||||
)
|
||||
})
|
||||
) : (
|
||||
<>
|
||||
<td className="px-2 py-1.5">
|
||||
<CellContent text={entry.english} field="english" rowChanges={rowChanges} />
|
||||
</td>
|
||||
<td className="px-2 py-1.5">
|
||||
<CellContent text={entry.german} field="german" rowChanges={rowChanges} />
|
||||
</td>
|
||||
<td className="px-2 py-1.5 text-xs">
|
||||
<CellContent text={entry.example} field="example" rowChanges={rowChanges} />
|
||||
</td>
|
||||
</>
|
||||
)}
|
||||
<td className="px-2 py-1.5 text-center">
|
||||
<StatusIcon status={rowStatus} />
|
||||
</td>
|
||||
|
||||
@@ -264,6 +264,8 @@ export function StepReconstruction({ sessionId, onNext }: StepReconstructionProp
|
||||
column_de: 'border-green-400/40 focus:border-green-500',
|
||||
column_example: 'border-orange-400/40 focus:border-orange-500',
|
||||
column_text: 'border-purple-400/40 focus:border-purple-500',
|
||||
page_ref: 'border-cyan-400/40 focus:border-cyan-500',
|
||||
column_marker: 'border-gray-400/40 focus:border-gray-500',
|
||||
}
|
||||
return colors[colType] || 'border-gray-400/40 focus:border-gray-500'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user