feat(admin): OCR admin pages — overview & model detail #265
@@ -41,10 +41,10 @@ let {
|
||||
<tbody>
|
||||
{#each senderModels as model (model.id)}
|
||||
<tr>
|
||||
<td class="border-brand-sand/50 border-b py-3">
|
||||
<td class="border-brand-sand/50 border-b">
|
||||
<a
|
||||
href="/admin/ocr/{model.personId}"
|
||||
class="text-brand-navy hover:underline focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:outline-none"
|
||||
class="inline-block py-3 text-brand-navy hover:underline focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:outline-none"
|
||||
>
|
||||
{personNames[model.personId] ?? model.personId}
|
||||
</a>
|
||||
@@ -58,10 +58,10 @@ let {
|
||||
<td class="border-brand-sand/50 border-b py-3">
|
||||
{model.correctedLinesAtTraining}
|
||||
</td>
|
||||
<td class="border-brand-sand/50 border-b py-3">
|
||||
<td class="border-brand-sand/50 border-b">
|
||||
<a
|
||||
href="/admin/ocr/{model.personId}"
|
||||
class="font-medium text-brand-navy hover:underline focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:outline-none"
|
||||
class="inline-block py-3 font-medium text-brand-navy hover:underline focus-visible:rounded-sm focus-visible:ring-2 focus-visible:ring-brand-navy focus-visible:outline-none"
|
||||
>{m.ocr_table_details()}</a
|
||||
>
|
||||
</td>
|
||||
|
||||
@@ -14,5 +14,5 @@ export const load: PageServerLoad = async ({ params, fetch }) => {
|
||||
throw error(result.response.status, getErrorMessage(code));
|
||||
}
|
||||
|
||||
return { history: result.data! };
|
||||
return { history: result.data!, personId: params.personId };
|
||||
};
|
||||
|
||||
@@ -3,8 +3,8 @@ import type { PageData } from './$types';
|
||||
import TrainingHistory from '$lib/components/TrainingHistory.svelte';
|
||||
import * as m from '$lib/paraglide/messages.js';
|
||||
|
||||
let { data, params }: { data: PageData; params: { personId: string } } = $props();
|
||||
const personName = $derived(data.history.personNames?.[params.personId] ?? 'Unknown');
|
||||
let { data }: { data: PageData } = $props();
|
||||
const personName = $derived(data.history.personNames?.[data.personId] ?? 'Unknown');
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-6 p-6">
|
||||
|
||||
36
frontend/src/routes/admin/ocr/[personId]/page.svelte.spec.ts
Normal file
36
frontend/src/routes/admin/ocr/[personId]/page.svelte.spec.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { afterEach, describe, it, expect } from 'vitest';
|
||||
import { cleanup, render } from 'vitest-browser-svelte';
|
||||
import { page } from 'vitest/browser';
|
||||
import Page from './+page.svelte';
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
describe('[personId] page', () => {
|
||||
it('shows person name from personNames map', async () => {
|
||||
const personId = '123e4567-e89b-12d3-a456-426614174000';
|
||||
render(Page, {
|
||||
data: {
|
||||
personId,
|
||||
history: {
|
||||
runs: [],
|
||||
personNames: { [personId]: 'Anna Müller' }
|
||||
}
|
||||
}
|
||||
});
|
||||
await expect.element(page.getByRole('heading', { level: 1 })).toHaveTextContent('Anna Müller');
|
||||
});
|
||||
|
||||
it('falls back to Unknown when person name is missing', async () => {
|
||||
const personId = '123e4567-e89b-12d3-a456-426614174000';
|
||||
render(Page, {
|
||||
data: {
|
||||
personId,
|
||||
history: {
|
||||
runs: [],
|
||||
personNames: {}
|
||||
}
|
||||
}
|
||||
});
|
||||
await expect.element(page.getByRole('heading', { level: 1 })).toHaveTextContent('Unknown');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user