feat(ocr): move training cards from system page to OCR overview page

OcrTrainingCard and SegmentationTrainingCard now live on the dedicated
OCR overview page. System page no longer fetches training info.
SegmentationTrainingCard updated to use shared TrainingRun type.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-18 10:52:23 +02:00
parent 9ff498a194
commit cea1234400
4 changed files with 10 additions and 36 deletions

View File

@@ -1,23 +1,12 @@
<script lang="ts">
import TrainingHistory from './TrainingHistory.svelte';
import { m } from '$lib/paraglide/messages.js';
interface Run {
id: string;
status: 'RUNNING' | 'DONE' | 'FAILED';
blockCount: number;
documentCount: number;
modelName: string;
errorMessage?: string;
triggeredBy?: string;
createdAt: string;
completedAt?: string;
}
import type { TrainingRun } from '$lib/types/training.js';
interface TrainingInfo {
availableSegBlocks?: number;
ocrServiceAvailable?: boolean;
runs?: Run[];
runs?: TrainingRun[];
}
interface Props {

View File

@@ -3,6 +3,8 @@ import type { PageData } from './$types';
import OcrHealthBar from './OcrHealthBar.svelte';
import OcrStatCards from './OcrStatCards.svelte';
import OcrModelsTable from './OcrModelsTable.svelte';
import OcrTrainingCard from '$lib/components/OcrTrainingCard.svelte';
import SegmentationTrainingCard from '$lib/components/SegmentationTrainingCard.svelte';
import * as m from '$lib/paraglide/messages.js';
let { data }: { data: PageData } = $props();
@@ -27,6 +29,12 @@ const { trainingInfo } = $derived(data);
availableSegBlocks={trainingInfo.availableSegBlocks ?? 0}
/>
<!-- Training -->
<div class="grid grid-cols-1 gap-4 lg:grid-cols-2">
<OcrTrainingCard trainingInfo={trainingInfo} />
<SegmentationTrainingCard trainingInfo={trainingInfo} />
</div>
<!-- Sender models -->
<div>
<div class="mb-3 flex items-center justify-between">

View File

@@ -1,13 +1,6 @@
<script lang="ts">
import { onDestroy } from 'svelte';
import { m } from '$lib/paraglide/messages.js';
import OcrTrainingCard from '$lib/components/OcrTrainingCard.svelte';
import SegmentationTrainingCard from '$lib/components/SegmentationTrainingCard.svelte';
import type { components } from '$lib/generated/api.js';
type TrainingInfo = components['schemas']['TrainingInfoResponse'];
let trainingInfo: TrainingInfo | null = $state(null);
let backfillResult: number | null = $state(null);
let backfillLoading = $state(false);
@@ -58,16 +51,8 @@ async function triggerImport() {
}
}
async function fetchTrainingInfo() {
const res = await fetch('/api/ocr/training-info');
if (res.ok) {
trainingInfo = await res.json();
}
}
$effect(() => {
fetchImportStatus();
fetchTrainingInfo();
});
onDestroy(() => stopPolling());
@@ -103,12 +88,6 @@ async function backfillFileHashes() {
<div class="flex-1 overflow-y-auto p-6">
<div class="mx-auto max-w-2xl space-y-5">
<!-- OCR Recognition Training -->
<OcrTrainingCard trainingInfo={trainingInfo} />
<!-- OCR Segmentation Training -->
<SegmentationTrainingCard trainingInfo={trainingInfo} />
<!-- Backfill versions -->
<div class="rounded-sm border border-line bg-surface p-6 shadow-sm">
<h2 class="mb-1 font-sans text-sm font-bold text-ink">{m.admin_system_backfill_heading()}</h2>

View File

@@ -78,8 +78,6 @@ describe('Admin system page — mass import card', () => {
startedAt: null
})
})
// training info fetch → empty
.mockResolvedValueOnce({ ok: true, json: async () => ({}) })
// trigger POST → returns RUNNING immediately
.mockResolvedValueOnce({
ok: true,