fix(ocr-pipeline): preserve sub-column data in vocab table display
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 26s
CI / test-go-edu-search (push) Successful in 26s
CI / test-python-klausur (push) Failing after 1m51s
CI / test-python-agent-core (push) Successful in 16s
CI / test-nodejs-website (push) Successful in 16s

Three fixes for sub-columns disappearing at end of streaming:

1. Backend: add column_marker mapping in _cells_to_vocab_entries()
   so marker text is included in vocab entries (not silently dropped)

2. Frontend types: add source_page and bbox_ref to WordEntry interface

3. Frontend table: show page_ref column (Seite) in vocab table when
   entries have source_page data, instead of only EN/DE/Example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-03 08:06:15 +01:00
parent 0d72f2c836
commit dea3349b23
3 changed files with 54 additions and 37 deletions

View File

@@ -518,43 +518,54 @@ export function StepWordRecognition({ sessionId, onNext, goToStep }: StepWordRec
{/* Entry/Cell table */}
<div className="max-h-80 overflow-y-auto">
{isVocab ? (
/* Vocab table: EN/DE/Example columns */
<table className="w-full text-xs">
<thead className="sticky top-0 bg-white dark:bg-gray-800">
<tr className="text-left text-gray-500 dark:text-gray-400 border-b dark:border-gray-700">
<th className="py-1 pr-2 w-8">#</th>
<th className="py-1 pr-2">English</th>
<th className="py-1 pr-2">Deutsch</th>
<th className="py-1 pr-2">Example</th>
<th className="py-1 w-12 text-right">Conf</th>
</tr>
</thead>
<tbody>
{editedEntries.map((entry, idx) => (
<tr
key={idx}
className={`border-b dark:border-gray-700/50 ${
idx === activeIndex ? 'bg-teal-50 dark:bg-teal-900/20' : ''
}`}
onClick={() => { setActiveIndex(idx); setMode('labeling') }}
>
<td className="py-1 pr-2 text-gray-400">{idx + 1}</td>
<td className="py-1 pr-2 font-mono text-gray-700 dark:text-gray-300 cursor-pointer">
<MultilineText text={entry.english} />
</td>
<td className="py-1 pr-2 font-mono text-gray-700 dark:text-gray-300 cursor-pointer">
<MultilineText text={entry.german} />
</td>
<td className="py-1 pr-2 font-mono text-gray-500 dark:text-gray-400 cursor-pointer max-w-[200px]">
<MultilineText text={entry.example} />
</td>
<td className={`py-1 text-right font-mono ${confColor(entry.confidence)}`}>
{entry.confidence}%
</td>
</tr>
))}
</tbody>
</table>
/* Vocab table: EN/DE/Example columns + optional page_ref */
(() => {
const hasPageRef = editedEntries.some(e => e.source_page)
return (
<table className="w-full text-xs">
<thead className="sticky top-0 bg-white dark:bg-gray-800">
<tr className="text-left text-gray-500 dark:text-gray-400 border-b dark:border-gray-700">
<th className="py-1 pr-2 w-8">#</th>
{hasPageRef && <th className="py-1 pr-2 w-12 text-gray-400">Seite</th>}
<th className="py-1 pr-2">English</th>
<th className="py-1 pr-2">Deutsch</th>
<th className="py-1 pr-2">Example</th>
<th className="py-1 w-12 text-right">Conf</th>
</tr>
</thead>
<tbody>
{editedEntries.map((entry, idx) => (
<tr
key={idx}
className={`border-b dark:border-gray-700/50 ${
idx === activeIndex ? 'bg-teal-50 dark:bg-teal-900/20' : ''
}`}
onClick={() => { setActiveIndex(idx); setMode('labeling') }}
>
<td className="py-1 pr-2 text-gray-400">{idx + 1}</td>
{hasPageRef && (
<td className="py-1 pr-2 font-mono text-gray-400 dark:text-gray-500">
{entry.source_page || ''}
</td>
)}
<td className="py-1 pr-2 font-mono text-gray-700 dark:text-gray-300 cursor-pointer">
<MultilineText text={entry.english} />
</td>
<td className="py-1 pr-2 font-mono text-gray-700 dark:text-gray-300 cursor-pointer">
<MultilineText text={entry.german} />
</td>
<td className="py-1 pr-2 font-mono text-gray-500 dark:text-gray-400 cursor-pointer max-w-[200px]">
<MultilineText text={entry.example} />
</td>
<td className={`py-1 text-right font-mono ${confColor(entry.confidence)}`}>
{entry.confidence}%
</td>
</tr>
))}
</tbody>
</table>
)
})()
) : (
/* Generic table: dynamic columns from columns_used */
<table className="w-full text-xs">