diff --git a/frontend/messages/de.json b/frontend/messages/de.json
index c033a147..c441cbf8 100644
--- a/frontend/messages/de.json
+++ b/frontend/messages/de.json
@@ -274,5 +274,21 @@
"upload_duplicate": "{filename} existiert bereits —",
"upload_duplicate_link": "Zum Dokument",
"upload_invalid_type": "{filename}: Dateiformat nicht unterstützt",
- "upload_error": "Fehler beim Hochladen von {filename}"
+ "upload_error": "Fehler beim Hochladen von {filename}",
+ "enrich_list_back": "Zurück zur Übersicht",
+ "enrich_list_count": "Dokumente",
+ "btn_save_and_mark_reviewed": "Speichern & abschließen",
+ "btn_mark_for_review": "Zur Überprüfung markieren",
+ "enrich_needs_metadata_title": "Dokumente ohne Metadaten",
+ "enrich_needs_metadata_count": "{count} Dokument(e) warten auf Metadaten",
+ "enrich_needs_metadata_cta": "Jetzt vervollständigen",
+ "enrich_list_heading": "Dokumente ohne Metadaten",
+ "enrich_list_empty_heading": "Alle Dokumente vollständig",
+ "enrich_list_empty_body": "Es gibt keine Dokumente, die noch Metadaten benötigen.",
+ "enrich_list_start": "Überprüfung starten",
+ "enrich_progress": "{count} verbleibend",
+ "enrich_skip": "Überspringen",
+ "enrich_done_heading": "Alles erledigt!",
+ "enrich_done_body": "Alle Dokumente wurden bearbeitet.",
+ "enrich_back_to_list": "Zurück zur Liste"
}
diff --git a/frontend/messages/en.json b/frontend/messages/en.json
index f9d53545..abd1c189 100644
--- a/frontend/messages/en.json
+++ b/frontend/messages/en.json
@@ -274,5 +274,21 @@
"upload_duplicate": "{filename} already exists —",
"upload_duplicate_link": "View document",
"upload_invalid_type": "{filename}: unsupported file format",
- "upload_error": "Error uploading {filename}"
+ "upload_error": "Error uploading {filename}",
+ "enrich_list_back": "Back to overview",
+ "enrich_list_count": "documents",
+ "btn_save_and_mark_reviewed": "Save & mark as reviewed",
+ "btn_mark_for_review": "Mark for review",
+ "enrich_needs_metadata_title": "Documents without metadata",
+ "enrich_needs_metadata_count": "{count} document(s) waiting for metadata",
+ "enrich_needs_metadata_cta": "Complete now",
+ "enrich_list_heading": "Documents without metadata",
+ "enrich_list_empty_heading": "All documents complete",
+ "enrich_list_empty_body": "There are no documents that still need metadata.",
+ "enrich_list_start": "Start reviewing",
+ "enrich_progress": "{count} remaining",
+ "enrich_skip": "Skip",
+ "enrich_done_heading": "All done!",
+ "enrich_done_body": "All documents have been processed.",
+ "enrich_back_to_list": "Back to list"
}
diff --git a/frontend/messages/es.json b/frontend/messages/es.json
index 958fb02e..0839bf4e 100644
--- a/frontend/messages/es.json
+++ b/frontend/messages/es.json
@@ -274,5 +274,21 @@
"upload_duplicate": "{filename} ya existe —",
"upload_duplicate_link": "Ver documento",
"upload_invalid_type": "{filename}: formato de archivo no admitido",
- "upload_error": "Error al subir {filename}"
+ "upload_error": "Error al subir {filename}",
+ "enrich_list_back": "Volver a la vista general",
+ "enrich_list_count": "documentos",
+ "btn_save_and_mark_reviewed": "Guardar y marcar como revisado",
+ "btn_mark_for_review": "Marcar para revisión",
+ "enrich_needs_metadata_title": "Documentos sin metadatos",
+ "enrich_needs_metadata_count": "{count} documento(s) esperando metadatos",
+ "enrich_needs_metadata_cta": "Completar ahora",
+ "enrich_list_heading": "Documentos sin metadatos",
+ "enrich_list_empty_heading": "Todos los documentos completos",
+ "enrich_list_empty_body": "No hay documentos que necesiten metadatos.",
+ "enrich_list_start": "Comenzar revisión",
+ "enrich_progress": "{count} restante(s)",
+ "enrich_skip": "Omitir",
+ "enrich_done_heading": "¡Todo listo!",
+ "enrich_done_body": "Todos los documentos han sido procesados.",
+ "enrich_back_to_list": "Volver a la lista"
}
diff --git a/frontend/src/lib/generated/api.ts b/frontend/src/lib/generated/api.ts
index 9659f8a1..c6fb5ac0 100644
--- a/frontend/src/lib/generated/api.ts
+++ b/frontend/src/lib/generated/api.ts
@@ -468,6 +468,54 @@ export interface paths {
patch?: never;
trace?: never;
};
+ "/api/documents/incomplete-count": {
+ parameters: {
+ query?: never;
+ header?: never;
+ path?: never;
+ cookie?: never;
+ };
+ get: operations["getIncompleteCount"];
+ put?: never;
+ post?: never;
+ delete?: never;
+ options?: never;
+ head?: never;
+ patch?: never;
+ trace?: never;
+ };
+ "/api/documents/incomplete": {
+ parameters: {
+ query?: never;
+ header?: never;
+ path?: never;
+ cookie?: never;
+ };
+ get: operations["getIncomplete"];
+ put?: never;
+ post?: never;
+ delete?: never;
+ options?: never;
+ head?: never;
+ patch?: never;
+ trace?: never;
+ };
+ "/api/documents/incomplete/next": {
+ parameters: {
+ query?: never;
+ header?: never;
+ path?: never;
+ cookie?: never;
+ };
+ get: operations["getNextIncomplete"];
+ put?: never;
+ post?: never;
+ delete?: never;
+ options?: never;
+ head?: never;
+ patch?: never;
+ trace?: never;
+ };
"/api/documents/search": {
parameters: {
query?: never;
@@ -1819,6 +1867,77 @@ export interface operations {
};
};
};
+ getIncompleteCount: {
+ parameters: {
+ query?: never;
+ header?: never;
+ path?: never;
+ cookie?: never;
+ };
+ requestBody?: never;
+ responses: {
+ /** @description OK */
+ 200: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ "*/*": {
+ count: number;
+ };
+ };
+ };
+ };
+ };
+ getIncomplete: {
+ parameters: {
+ query?: never;
+ header?: never;
+ path?: never;
+ cookie?: never;
+ };
+ requestBody?: never;
+ responses: {
+ /** @description OK */
+ 200: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ "*/*": components["schemas"]["Document"][];
+ };
+ };
+ };
+ };
+ getNextIncomplete: {
+ parameters: {
+ query: {
+ excludeId: string;
+ };
+ header?: never;
+ path?: never;
+ cookie?: never;
+ };
+ requestBody?: never;
+ responses: {
+ /** @description OK */
+ 200: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ "*/*": components["schemas"]["Document"];
+ };
+ };
+ /** @description No Content */
+ 204: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content?: never;
+ };
+ };
+ };
importStatus: {
parameters: {
query?: never;
diff --git a/frontend/src/routes/+page.server.ts b/frontend/src/routes/+page.server.ts
index b9ed284a..248fc783 100644
--- a/frontend/src/routes/+page.server.ts
+++ b/frontend/src/routes/+page.server.ts
@@ -12,7 +12,7 @@ export async function load({ url, fetch }) {
const api = createApiClient(fetch);
try {
- const [docsResult, personsResult] = await Promise.all([
+ const [docsResult, personsResult, incompleteCountResult] = await Promise.all([
api.GET('/api/documents/search', {
params: {
query: {
@@ -25,7 +25,8 @@ export async function load({ url, fetch }) {
}
}
}),
- api.GET('/api/persons')
+ api.GET('/api/persons'),
+ api.GET('/api/documents/incomplete-count')
]);
if (docsResult.response.status === 401 || personsResult.response.status === 401) {
@@ -39,8 +40,13 @@ export async function load({ url, fetch }) {
const senderObj = allPersons.find((p) => p.id === senderId);
const receiverObj = allPersons.find((p) => p.id === receiverId);
+ const incompleteCount = incompleteCountResult.response.ok
+ ? (incompleteCountResult.data?.count ?? 0)
+ : 0;
+
return {
documents,
+ incompleteCount,
initialValues: {
senderName: senderObj ? `${senderObj.firstName} ${senderObj.lastName}` : '',
receiverName: receiverObj ? `${receiverObj.firstName} ${receiverObj.lastName}` : ''
@@ -53,6 +59,7 @@ export async function load({ url, fetch }) {
console.error('Error loading data:', e);
return {
documents: [],
+ incompleteCount: 0,
initialValues: { senderName: '', receiverName: '' },
filters: { q, from, to, senderId, receiverId, tags },
error: 'Daten konnten nicht geladen werden.' as string | null
diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte
index e5130ff1..57f40f8e 100644
--- a/frontend/src/routes/+page.svelte
+++ b/frontend/src/routes/+page.svelte
@@ -5,6 +5,7 @@ import { SvelteURLSearchParams } from 'svelte/reactivity';
import SearchFilterBar from './SearchFilterBar.svelte';
import DropZone from './DropZone.svelte';
import DocumentList from './DocumentList.svelte';
+import { m } from '$lib/paraglide/messages.js';
let { data } = $props();
@@ -86,5 +87,34 @@ $effect(() => {
+ {m.enrich_needs_metadata_title()}
+
+ {m.enrich_needs_metadata_count({ count: data.incompleteCount })}
+
+ {count} + {m.enrich_list_count()} +
+ {/if} ++ {m.enrich_list_empty_heading()} +
++ {m.enrich_list_empty_body()} +
++ {doc.title || doc.originalFilename} +
++ {formatUploadDate(doc.createdAt)} +
++ {doc.title || doc.originalFilename} +
+ ++ {m.enrich_progress({ count: data.incompleteCount })} +
++ {m.enrich_done_body()} +
+ + +