From 660e34e01659be789233f8b400f33646e89c3383 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sat, 25 Apr 2026 14:52:10 +0200 Subject: [PATCH] feat(bulk-edit): add i18n keys, error mapping, and regenerate api types - 14 new Paraglide keys in de/en/es for the bulk-edit UI strings (selection bar, callout, badges, save progress, retry, error) - BULK_EDIT_TOO_MANY_IDS added to errors.ts type union and getErrorMessage() - Regenerated api.ts now includes /api/documents/{bulk,batch-metadata,ids} and the DocumentBulkEditDTO / BulkEditResult / DocumentBatchSummary schemas Refs #225 Co-Authored-By: Claude Sonnet 4.6 --- frontend/messages/de.json | 16 ++- frontend/messages/en.json | 16 ++- frontend/messages/es.json | 16 ++- frontend/src/lib/errors.ts | 3 + frontend/src/lib/generated/api.ts | 157 +++++++++++++++++++++++++++++- 5 files changed, 204 insertions(+), 4 deletions(-) diff --git a/frontend/messages/de.json b/frontend/messages/de.json index fe3ecb42..5642db93 100644 --- a/frontend/messages/de.json +++ b/frontend/messages/de.json @@ -873,5 +873,19 @@ "bulk_drop_zone_label": "Dateien ablegen", "bulk_remove_file": "Entfernen", "bulk_title_single": "Neues Dokument", - "bulk_title_multi": "Neue Dokumente" + "bulk_title_multi": "Neue Dokumente", + "bulk_edit_button": "Massenbearbeitung", + "bulk_edit_n_selected": "{count} Dokumente ausgewählt", + "bulk_edit_clear_all": "Alles aufheben", + "bulk_edit_all_x": "Alle {count} editieren", + "bulk_edit_select_document": "Dokument {title} auswählen", + "bulk_edit_hint": "Nur ausgefüllte Felder werden angewendet. Tags und Empfänger werden hinzugefügt, nicht ersetzt.", + "bulk_edit_badge_additive": "+ wird hinzugefügt", + "bulk_edit_badge_replace": "wird ersetzt", + "bulk_edit_save_progress": "Batch {done} von {total} verarbeitet", + "bulk_edit_save_partial": "{done} von {total} gespeichert", + "bulk_edit_retry": "Erneut versuchen", + "bulk_edit_title": "Massenbearbeitung", + "bulk_edit_save_button": "Anwenden", + "error_bulk_edit_too_many_ids": "Maximal 500 Dokumente pro Anfrage." } diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 1699a911..50f2399f 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -873,5 +873,19 @@ "bulk_drop_zone_label": "Drop files here", "bulk_remove_file": "Remove", "bulk_title_single": "New Document", - "bulk_title_multi": "New Documents" + "bulk_title_multi": "New Documents", + "bulk_edit_button": "Bulk edit", + "bulk_edit_n_selected": "{count} documents selected", + "bulk_edit_clear_all": "Clear all", + "bulk_edit_all_x": "Edit all {count}", + "bulk_edit_select_document": "Select document {title}", + "bulk_edit_hint": "Only filled fields are applied. Tags and receivers are added, not replaced.", + "bulk_edit_badge_additive": "+ added", + "bulk_edit_badge_replace": "replaced", + "bulk_edit_save_progress": "Batch {done} of {total} processed", + "bulk_edit_save_partial": "{done} of {total} saved", + "bulk_edit_retry": "Retry", + "bulk_edit_title": "Bulk edit", + "bulk_edit_save_button": "Apply", + "error_bulk_edit_too_many_ids": "Maximum 500 documents per request." } diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 61fba34c..0cd956ab 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -873,5 +873,19 @@ "bulk_drop_zone_label": "Soltar archivos aquí", "bulk_remove_file": "Eliminar", "bulk_title_single": "Nuevo Documento", - "bulk_title_multi": "Nuevos Documentos" + "bulk_title_multi": "Nuevos Documentos", + "bulk_edit_button": "Edición masiva", + "bulk_edit_n_selected": "{count} documentos seleccionados", + "bulk_edit_clear_all": "Limpiar todo", + "bulk_edit_all_x": "Editar los {count}", + "bulk_edit_select_document": "Seleccionar documento {title}", + "bulk_edit_hint": "Solo se aplican los campos rellenados. Las etiquetas y los destinatarios se añaden, no se reemplazan.", + "bulk_edit_badge_additive": "+ se añade", + "bulk_edit_badge_replace": "se reemplaza", + "bulk_edit_save_progress": "Lote {done} de {total} procesado", + "bulk_edit_save_partial": "{done} de {total} guardado", + "bulk_edit_retry": "Reintentar", + "bulk_edit_title": "Edición masiva", + "bulk_edit_save_button": "Aplicar", + "error_bulk_edit_too_many_ids": "Máximo 500 documentos por solicitud." } diff --git a/frontend/src/lib/errors.ts b/frontend/src/lib/errors.ts index 1a1d1551..eec7a3e1 100644 --- a/frontend/src/lib/errors.ts +++ b/frontend/src/lib/errors.ts @@ -42,6 +42,7 @@ export type ErrorCode = | 'FORBIDDEN' | 'VALIDATION_ERROR' | 'BATCH_TOO_LARGE' + | 'BULK_EDIT_TOO_MANY_IDS' | 'INTERNAL_ERROR'; export interface BackendError { @@ -142,6 +143,8 @@ export function getErrorMessage(code: ErrorCode | string | undefined): string { return m.error_validation_error(); case 'BATCH_TOO_LARGE': return m.error_batch_too_large(); + case 'BULK_EDIT_TOO_MANY_IDS': + return m.error_bulk_edit_too_many_ids(); default: return m.error_internal_error(); } diff --git a/frontend/src/lib/generated/api.ts b/frontend/src/lib/generated/api.ts index 3c2e8036..81925006 100644 --- a/frontend/src/lib/generated/api.ts +++ b/frontend/src/lib/generated/api.ts @@ -484,6 +484,22 @@ export interface paths { patch?: never; trace?: never; }; + "/api/documents/batch-metadata": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: operations["batchMetadata"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/auth/reset-password": { parameters: { query?: never; @@ -676,6 +692,22 @@ export interface paths { patch: operations["updateAnnotation"]; trace?: never; }; + "/api/documents/bulk": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch: operations["patchBulk"]; + trace?: never; + }; "/api/users/search": { parameters: { query?: never; @@ -1156,6 +1188,22 @@ export interface paths { patch?: never; trace?: never; }; + "/api/documents/ids": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: operations["getDocumentIds"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/documents/conversation": { parameters: { query?: never; @@ -1707,6 +1755,15 @@ export interface components { filename?: string; code?: string; }; + BatchMetadataRequest: { + ids: string[]; + }; + DocumentBatchSummary: { + /** Format: uuid */ + id: string; + title: string; + pdfUrl: string; + }; ResetPasswordRequest: { token?: string; newPassword?: string; @@ -1782,6 +1839,26 @@ export interface components { /** Format: double */ height?: number; }; + DocumentBulkEditDTO: { + documentIds?: string[]; + tagNames?: string[]; + /** Format: uuid */ + senderId?: string; + receiverIds?: string[]; + documentLocation?: string; + archiveBox?: string; + archiveFolder?: string; + }; + BulkEditError: { + /** Format: uuid */ + id: string; + message: string; + }; + BulkEditResult: { + /** Format: int32 */ + updated: number; + errors: components["schemas"]["BulkEditError"][]; + }; TranscriptionWeeklyStatsDTO: { /** Format: int64 */ segmentationCount: number; @@ -1833,7 +1910,6 @@ export interface components { /** Format: uuid */ id?: string; displayName?: string; - personType?: string; firstName?: string; lastName?: string; /** Format: int64 */ @@ -1844,6 +1920,7 @@ export interface components { deathYear?: number; alias?: string; notes?: string; + personType?: string; }; SenderModel: { /** Format: uuid */ @@ -3242,6 +3319,30 @@ export interface operations { }; }; }; + batchMetadata: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["BatchMetadataRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "*/*": components["schemas"]["DocumentBatchSummary"][]; + }; + }; + }; + }; resetPassword: { parameters: { query?: never; @@ -3578,6 +3679,30 @@ export interface operations { }; }; }; + patchBulk: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["DocumentBulkEditDTO"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "*/*": components["schemas"]["BulkEditResult"]; + }; + }; + }; + }; search: { parameters: { query?: { @@ -4244,6 +4369,36 @@ export interface operations { }; }; }; + getDocumentIds: { + parameters: { + query?: { + q?: string; + from?: string; + to?: string; + senderId?: string; + receiverId?: string; + tag?: string[]; + tagQ?: string; + status?: "PLACEHOLDER" | "UPLOADED" | "TRANSCRIBED" | "REVIEWED" | "ARCHIVED"; + tagOp?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "*/*": string[]; + }; + }; + }; + }; getConversation: { parameters: { query: {