From bd070cab6351ec9c2e4c1a6db5bac81cd4ec314a Mon Sep 17 00:00:00 2001 From: RamGopalSrikar Date: Mon, 13 Apr 2026 15:21:36 -0400 Subject: [PATCH] feat(i18n): translate Create Knowledge Base modal and flow dropdown menu --- src/frontend/src/locales/de.json | 45 ++++++++++++++++++- src/frontend/src/locales/en.json | 43 ++++++++++++++++++ src/frontend/src/locales/es.json | 45 ++++++++++++++++++- src/frontend/src/locales/fr.json | 45 ++++++++++++++++++- src/frontend/src/locales/ja.json | 45 ++++++++++++++++++- src/frontend/src/locales/pt.json | 45 ++++++++++++++++++- src/frontend/src/locales/zh-Hans.json | 45 ++++++++++++++++++- .../KnowledgeBaseUploadModal.tsx | 22 ++++++--- .../components/StepConfiguration.tsx | 41 +++++++++-------- .../knowledgeBaseUploadModal/constants.ts | 17 +++---- .../hooks/useKnowledgeBaseForm.ts | 26 ++++++----- .../MainPage/components/dropdown/index.tsx | 14 +++--- 12 files changed, 374 insertions(+), 59 deletions(-) diff --git a/src/frontend/src/locales/de.json b/src/frontend/src/locales/de.json index 0984cf2804..87b57a6eb0 100644 --- a/src/frontend/src/locales/de.json +++ b/src/frontend/src/locales/de.json @@ -160,6 +160,11 @@ "flow.brokenEdgesWarning": "Einige Verbindungen wurden entfernt, da sie ungültig waren:", "flow.buildStatus": "Erstellen, um den Status zu überprüfen.", "flow.buildSuccess": "Erfolgreich erstellt ✨", + "flow.duplicatedSuccess": "{{type}} Erfolgreich dupliziert", + "flow.menu.delete": "Löschen", + "flow.menu.duplicate": "Duplikat", + "flow.menu.editDetails": "Details bearbeiten", + "flow.menu.export": "Exportieren", "flow.missingFields": "Bitte füllen Sie alle Pflichtfelder aus.", "flow.noCompatibleComponents": "Es wurden keine kompatiblen Komponenten gefunden.", "flow.runTimestampPrefix": "Letzter Lauf: ", @@ -210,30 +215,68 @@ "input.titleErrorUpdatingComponent": "Fehler beim Aktualisieren der Komponente", "input.toolsetPlaceholder": "Als Werkzeug verwendet", "knowledge.addKnowledge": "Wissen hinzufügen", + "knowledge.addSources": "Quellen hinzufügen", + "knowledge.addSourcesDescription": "Dateien hochladen und Chunking-Einstellungen konfigurieren", + "knowledge.addSourcesTitle": "Quellen hinzufügen", "knowledge.baseCreated": "Wissensdatenbank \"{{name}}\" erstellt", + "knowledge.chunkOverlapLabel": "Chunk-Überlappung", + "knowledge.chunkOverlapTooltip": "Anzahl der Zeichen, die sich zwischen den Blöcken überlappen sollen.", + "knowledge.chunkSizeLabel": "Chunkgröße", + "knowledge.chunkSizeTooltip": "Die maximale Länge jedes Chunks. Der Text wird zunächst anhand des Trennzeichens aufgeteilt, anschließend werden die Teile bis zu dieser Größe zusammengefügt.", + "knowledge.chunkingSettings": "Einstellungen für die Chunking-Funktion", + "knowledge.configureSources": "Quellen konfigurieren", + "knowledge.configureSourcesMaxSize": "(maximal 1 GB Upload)", + "knowledge.createDescription": "Geben Sie Ihrer Wissensdatenbank einen Namen, laden Sie Quellen hoch und wählen Sie ein Einbettungsmodell aus", + "knowledge.createTitle": "Wissensdatenbank erstellen", "knowledge.delete": "Löschen", "knowledge.deleteSelected": "Löschen ( {{count}} )", "knowledge.deletedCount": "{{count}} Wissensdatenbank(en) gelöscht", + "knowledge.embeddingModelLabel": "Einbettungsmodell", + "knowledge.embeddingModelPlaceholder": "Einbettungsmodell auswählen", + "knowledge.embeddingModelUnknown": "Unbekannt", "knowledge.emptyDescription": "Schaffen Sie leistungsstarke KI-Anwendungen, indem Sie Ihre Dokumente mit intelligenten Arbeitsabläufen verknüpfen.", + "knowledge.errorChunkPreview": "Die Vorschau des Chunks konnte nicht generiert werden", + "knowledge.errorCreateFailed": "Die Erstellung der Wissensdatenbank ist fehlgeschlagen", + "knowledge.errorIngestion": "Die Erfassung für \"{{name}}\" konnte nicht gestartet werden", "knowledge.failedToDelete": "Das Löschen der Wissensdatenbanken ist fehlgeschlagen", "knowledge.failedToLoad": "Das Laden der Wissensdatenbanken ist fehlgeschlagen", "knowledge.failedToLoadChunks": "Chunks konnten nicht geladen werden", + "knowledge.helpConfigureSources": "Quellen konfigurieren", + "knowledge.helpHideConfiguration": "Konfiguration ausblenden", "knowledge.ingestionComplete": "\"{{name}}\" Import abgeschlossen — {{chunks}} Blöcke bereit", "knowledge.ingestionFailed": "Die Einbindung von \"{{name}}\" ist fehlgeschlagen", "knowledge.loadingChunks": "Chunks werden geladen...", "knowledge.loadingKnowledgeBases": "Wissensdatenbanken werden geladen...", + "knowledge.nameLabel": "Ihren Namen", + "knowledge.namePlaceholder": "Geben Sie einen Namen für diese Wissensdatenbank ein", "knowledge.noChunksFound": "Es wurden keine Chunks gefunden", "knowledge.noKnowledgeBases": "Keine Wissensdatenbanken", "knowledge.ofTotal": "von {{total}}", "knowledge.page": "Seite", "knowledge.pageTitle": "Wissen", "knowledge.perPage": "Pro Seite:", + "knowledge.reviewDescription": "Zeigen Sie in der Vorschau an, wie Ihre Dateien aufgeteilt werden, und bestätigen Sie Ihre Einstellungen", + "knowledge.reviewTitle": "Überprüfen & Erstellen", "knowledge.searchChunks": "Chunks suchen...", "knowledge.searchPlaceholder": "Wissensdatenbanken durchsuchen...", "knowledge.selected": "{{count}} ausgewählt", + "knowledge.separatorLabel": "Trennzeichen", + "knowledge.separatorTooltip": "Das Zeichen, an dem die Trennung erfolgen soll. Verwende \\n für einen Zeilenumbruch. Beispiele: \\n\\n für Absätze, \\n für Zeilen,. für Sätze. Lassen Sie das Feld leer, wenn kein Trennzeichen gewünscht ist.", "knowledge.showing": "Anzeige von {{start}} – {{end}} von {{total}} -Blöcken", + "knowledge.sourcesLabel": "Quellen", + "knowledge.submitAddSources": "Quellen hinzufügen", + "knowledge.submitCreate": "Erstellen", + "knowledge.successSourcesAdded": "Quellen wurden zu „ \"{{name}}\" “ hinzugefügt", "knowledge.thisActionCannotBeUndone": "Diese Aktion kann nicht rückgängig gemacht werden", "knowledge.unknownError": "Es ist ein unbekannter Fehler aufgetreten", + "knowledge.uploadFiles": "Dateien hochladen", + "knowledge.uploadFolder": "Ordner hochladen", + "knowledge.validationEmbeddingRequired": "Ein Einbettungsmodell ist erforderlich", + "knowledge.validationFileSizeLimit": "Die Gesamtdateigröße überschreitet das Limit von 1 GB", + "knowledge.validationNameDuplicate": "Eine Wissensdatenbank mit diesem Namen existiert bereits", + "knowledge.validationNameFormat": "Der Name darf nur [ a-zA-Z0-9._-] enthalten und muss mit [ a-zA-Z0-9 ] beginnen und enden", + "knowledge.validationNameLength": "Der Name muss zwischen 3 und 512 Zeichen lang sein", + "knowledge.validationNameRequired": "Name ist erforderlich", "mainPage.delete": "Löschen", "mainPage.flowsDeletedSuccess": "Flows wurden erfolgreich gelöscht", "mainPage.flowsDownloadedSuccess": "Die Flows wurden erfolgreich heruntergeladen", @@ -485,4 +528,4 @@ "templatesModal.title": "Vorlagen", "templatesModal.tryDifferentQuery": "und versuchen Sie es mit einer anderen Abfrage.", "templatesModal.useCases": "Anwendungsfälle" -} +} \ No newline at end of file diff --git a/src/frontend/src/locales/en.json b/src/frontend/src/locales/en.json index e3a8a8da07..1f5fa0a4fc 100644 --- a/src/frontend/src/locales/en.json +++ b/src/frontend/src/locales/en.json @@ -47,6 +47,11 @@ "alerts.criticalDataWarning": "Warning: Critical data, JSON file may include API keys.", "alerts.apiKeyCopied": "API Key copied!", "alerts.noTemplateVariables": "Your template does not have any variables.", + "flow.menu.editDetails": "Edit details", + "flow.menu.export": "Export", + "flow.menu.duplicate": "Duplicate", + "flow.menu.delete": "Delete", + "flow.duplicatedSuccess": "{{type}} duplicated successfully", "dialog.export": "Export flow as JSON file.", "dialog.settings": "Customize your flow details and settings.", "dialog.logs": "Explore detailed logs of events and transactions between components.", @@ -451,6 +456,44 @@ "knowledge.showing": "Showing {{start}}-{{end}} of {{total}} chunks", "knowledge.page": "Page", "knowledge.ofTotal": "of {{total}}", + "knowledge.createTitle": "Create Knowledge Base", + "knowledge.addSourcesTitle": "Add Sources", + "knowledge.reviewTitle": "Review & Build", + "knowledge.createDescription": "Name your knowledge base, upload sources, and select an embedding model", + "knowledge.addSourcesDescription": "Upload files and configure chunking settings", + "knowledge.reviewDescription": "Preview how your files will be chunked and confirm your settings", + "knowledge.nameLabel": "Name", + "knowledge.namePlaceholder": "Enter a name for this knowledge base", + "knowledge.embeddingModelLabel": "Embedding Model", + "knowledge.embeddingModelPlaceholder": "Select embedding model", + "knowledge.embeddingModelUnknown": "Unknown", + "knowledge.configureSources": "Configure Sources", + "knowledge.configureSourcesMaxSize": "(1 GB max upload)", + "knowledge.sourcesLabel": "Sources", + "knowledge.addSources": "Add Sources", + "knowledge.uploadFiles": "Upload Files", + "knowledge.uploadFolder": "Upload Folder", + "knowledge.chunkingSettings": "Chunking Settings", + "knowledge.chunkSizeLabel": "Chunk Size", + "knowledge.chunkSizeTooltip": "The maximum length of each chunk. Text is first split by separator, then chunks are merged up to this size.", + "knowledge.chunkOverlapLabel": "Chunk Overlap", + "knowledge.chunkOverlapTooltip": "Number of characters to overlap between chunks.", + "knowledge.separatorLabel": "Separator", + "knowledge.separatorTooltip": "The character to split on. Use \\n for newline. Examples: \\n\\n for paragraphs, \\n for lines, . for sentences. Leave blank for no separator.", + "knowledge.submitCreate": "Create", + "knowledge.submitAddSources": "Add Sources", + "knowledge.helpConfigureSources": "Configure Sources", + "knowledge.helpHideConfiguration": "Hide Configuration", + "knowledge.validationNameRequired": "Name is required", + "knowledge.validationNameLength": "Name must be between 3 and 512 characters", + "knowledge.validationNameFormat": "Name must only contain [a-zA-Z0-9._-] and start/end with [a-zA-Z0-9]", + "knowledge.validationNameDuplicate": "A knowledge base with this name already exists", + "knowledge.validationEmbeddingRequired": "Embedding model is required", + "knowledge.validationFileSizeLimit": "Total file size exceeds the 1 GB limit", + "knowledge.errorChunkPreview": "Failed to generate chunk preview", + "knowledge.errorIngestion": "Failed to start ingestion for \"{{name}}\"", + "knowledge.errorCreateFailed": "Failed to create knowledge base", + "knowledge.successSourcesAdded": "Sources added to \"{{name}}\"", "files.myFiles": "My Files", "files.pageTitle": "Files", "files.noFiles": "No files", diff --git a/src/frontend/src/locales/es.json b/src/frontend/src/locales/es.json index 57d25e6049..1908d96206 100644 --- a/src/frontend/src/locales/es.json +++ b/src/frontend/src/locales/es.json @@ -160,6 +160,11 @@ "flow.brokenEdgesWarning": "Se han eliminado algunas conexiones porque no eran válidas:", "flow.buildStatus": "Compilar para comprobar el estado.", "flow.buildSuccess": "Creado con éxito ✨", + "flow.duplicatedSuccess": "{{type}} se ha duplicado correctamente", + "flow.menu.delete": "Suprimir", + "flow.menu.duplicate": "Duplicado", + "flow.menu.editDetails": "Editar detalles", + "flow.menu.export": "Exportar", "flow.missingFields": "Rellene todos los campos obligatorios.", "flow.noCompatibleComponents": "No se han encontrado componentes compatibles.", "flow.runTimestampPrefix": "Última carrera: ", @@ -210,30 +215,68 @@ "input.titleErrorUpdatingComponent": "Se ha producido un error al actualizar el componente", "input.toolsetPlaceholder": "Se utiliza como herramienta", "knowledge.addKnowledge": "Añadir conocimiento", + "knowledge.addSources": "Añadir orígenes", + "knowledge.addSourcesDescription": "Sube archivos y configura los ajustes de fragmentación", + "knowledge.addSourcesTitle": "Añadir orígenes", "knowledge.baseCreated": "Se ha creado la base de conocimientos \"{{name}}\"", + "knowledge.chunkOverlapLabel": "Solapamiento de fragmentos", + "knowledge.chunkOverlapTooltip": "Número de caracteres que deben solaparse entre fragmentos.", + "knowledge.chunkSizeLabel": "Tamaño de fragmento", + "knowledge.chunkSizeTooltip": "La longitud máxima de cada fragmento. El texto se divide primero por el separador y, a continuación, los fragmentos se fusionan hasta alcanzar este tamaño.", + "knowledge.chunkingSettings": "Configuración de fragmentación", + "knowledge.configureSources": "Configurar fuentes", + "knowledge.configureSourcesMaxSize": "(1 GB como máximo de subida)", + "knowledge.createDescription": "Asigna un nombre a tu base de conocimientos, sube las fuentes y selecciona un modelo de integración", + "knowledge.createTitle": "Crear una base de conocimientos", "knowledge.delete": "Suprimir", "knowledge.deleteSelected": "Eliminar ( {{count}} )", "knowledge.deletedCount": "{{count}} Se han eliminado las bases de conocimientos", + "knowledge.embeddingModelLabel": "Modelo de inclusión", + "knowledge.embeddingModelPlaceholder": "Seleccionar modelo de incrustación", + "knowledge.embeddingModelUnknown": "Desconocido", "knowledge.emptyDescription": "Crea potentes experiencias de IA conectando tus documentos a flujos de trabajo inteligentes.", + "knowledge.errorChunkPreview": "No se ha podido generar la vista previa del fragmento", + "knowledge.errorCreateFailed": "No se ha podido crear la base de conocimientos", + "knowledge.errorIngestion": "No se ha podido iniciar la ingesta para \"{{name}}\"", "knowledge.failedToDelete": "No se han podido eliminar las bases de conocimientos", "knowledge.failedToLoad": "No se han podido cargar las bases de conocimientos", "knowledge.failedToLoadChunks": "No se han podido cargar los fragmentos", + "knowledge.helpConfigureSources": "Configurar fuentes", + "knowledge.helpHideConfiguration": "Ocultar configuración", "knowledge.ingestionComplete": "\"{{name}}\" Ingestión completada — {{chunks}} fragmentos listos", "knowledge.ingestionFailed": "Error al importar \"{{name}}\"", "knowledge.loadingChunks": "Cargando fragmentos...", "knowledge.loadingKnowledgeBases": "Cargando bases de datos...", + "knowledge.nameLabel": "Nombre", + "knowledge.namePlaceholder": "Introduce un nombre para esta base de conocimientos", "knowledge.noChunksFound": "No se han encontrado fragmentos", "knowledge.noKnowledgeBases": "No hay bases de conocimientos", "knowledge.ofTotal": "de {{total}}", "knowledge.page": "Página", "knowledge.pageTitle": "Conocimientos", "knowledge.perPage": "Por página:", + "knowledge.reviewDescription": "Previsualiza cómo se dividirán tus archivos y confirma la configuración", + "knowledge.reviewTitle": "Revisión y montaje", "knowledge.searchChunks": "Buscar fragmentos...", "knowledge.searchPlaceholder": "Buscar en las bases de conocimientos...", "knowledge.selected": "{{count}} seleccionados", + "knowledge.separatorLabel": "Separador", + "knowledge.separatorTooltip": "El carácter en el que se va a dividir. Utiliza \\n para crear un salto de línea. Ejemplos: \\n\\n para párrafos, \\n para líneas,. para las frases. Déjelo en blanco si no desea ningún separador.", "knowledge.showing": "Mostrando {{start}} - {{end}} de {{total}} fragmentos", + "knowledge.sourcesLabel": "Orígenes", + "knowledge.submitAddSources": "Añadir orígenes", + "knowledge.submitCreate": "Crear", + "knowledge.successSourcesAdded": "Fuentes añadidas a \"{{name}}\"", "knowledge.thisActionCannotBeUndone": "Esta acción no se puede deshacer", "knowledge.unknownError": "Se ha producido un error desconocido", + "knowledge.uploadFiles": "Cargar archivos", + "knowledge.uploadFolder": "Carpeta de carga", + "knowledge.validationEmbeddingRequired": "Se requiere un modelo de incrustación", + "knowledge.validationFileSizeLimit": "El tamaño total del archivo supera el límite de 1 GB", + "knowledge.validationNameDuplicate": "Ya existe una base de conocimientos con ese nombre", + "knowledge.validationNameFormat": "El nombre solo debe contener [ a-zA-Z0-9._-] y comenzar y terminar con [ a-zA-Z0-9 ]", + "knowledge.validationNameLength": "El nombre debe tener entre 3 y 512 caracteres", + "knowledge.validationNameRequired": "El nombre es obligatorio", "mainPage.delete": "Suprimir", "mainPage.flowsDeletedSuccess": "Los flujos se han eliminado correctamente", "mainPage.flowsDownloadedSuccess": "Los flujos se han descargado correctamente", @@ -485,4 +528,4 @@ "templatesModal.title": "Plantillas", "templatesModal.tryDifferentQuery": "y prueba con otra consulta.", "templatesModal.useCases": "Casos de uso" -} +} \ No newline at end of file diff --git a/src/frontend/src/locales/fr.json b/src/frontend/src/locales/fr.json index b226410b0d..9da7eb6405 100644 --- a/src/frontend/src/locales/fr.json +++ b/src/frontend/src/locales/fr.json @@ -160,6 +160,11 @@ "flow.brokenEdgesWarning": "Certaines connexions ont été supprimées car elles n'étaient pas valides :", "flow.buildStatus": "Compiler pour vérifier l'état.", "flow.buildSuccess": "Réussite ✨", + "flow.duplicatedSuccess": "{{type}} copie effectuée avec succès", + "flow.menu.delete": "Supprimer", + "flow.menu.duplicate": "Dupliquer", + "flow.menu.editDetails": "Editer les détails", + "flow.menu.export": "Exporter", "flow.missingFields": "Veuillez remplir tous les champs obligatoires.", "flow.noCompatibleComponents": "Aucun composant compatible n'a été trouvé.", "flow.runTimestampPrefix": "Dernière course : ", @@ -210,30 +215,68 @@ "input.titleErrorUpdatingComponent": "Erreur lors de la mise à jour du composant", "input.toolsetPlaceholder": "Utilisé comme outil", "knowledge.addKnowledge": "Ajouter des connaissances", + "knowledge.addSources": "Ajouter des sources", + "knowledge.addSourcesDescription": "Télécharger des fichiers et configurer les paramètres de fractionnement", + "knowledge.addSourcesTitle": "Ajouter des sources", "knowledge.baseCreated": "Création de la base de connaissances \"{{name}}\"", + "knowledge.chunkOverlapLabel": "Chevauchement de blocs", + "knowledge.chunkOverlapTooltip": "Nombre de caractères à faire chevaucher entre les segments.", + "knowledge.chunkSizeLabel": "Taille de bloc", + "knowledge.chunkSizeTooltip": "La longueur maximale de chaque bloc. Le texte est d'abord divisé à l'aide d'un séparateur, puis les segments sont regroupés jusqu'à atteindre cette taille.", + "knowledge.chunkingSettings": "Paramètres de segmentation", + "knowledge.configureSources": "Configurer les sources", + "knowledge.configureSourcesMaxSize": "(1 Go max. pour le téléchargement)", + "knowledge.createDescription": "Donnez un nom à votre base de connaissances, téléchargez les sources et sélectionnez un modèle d'intégration", + "knowledge.createTitle": "Créer une base de connaissances", "knowledge.delete": "Supprimer", "knowledge.deleteSelected": "Supprimer ( {{count}} )", "knowledge.deletedCount": "{{count}} base(s) de connaissances supprimée(s)", + "knowledge.embeddingModelLabel": "Modèle d'intégration", + "knowledge.embeddingModelPlaceholder": "Sélectionner un modèle d'intégration", + "knowledge.embeddingModelUnknown": "Inconnu", "knowledge.emptyDescription": "Créez des expériences d'IA performantes en intégrant vos documents à des flux de travail intelligents.", + "knowledge.errorChunkPreview": "Échec de la génération de l'aperçu du bloc", + "knowledge.errorCreateFailed": "Échec de la création de la base de connaissances", + "knowledge.errorIngestion": "Échec du démarrage de l'ingestion pour \"{{name}}\"", "knowledge.failedToDelete": "Échec de la suppression des bases de connaissances", "knowledge.failedToLoad": "Échec du chargement des bases de connaissances", "knowledge.failedToLoadChunks": "Échec du chargement des blocs", + "knowledge.helpConfigureSources": "Configurer les sources", + "knowledge.helpHideConfiguration": "Masquer la configuration", "knowledge.ingestionComplete": "\"{{name}}\" Importation terminée — {{chunks}} morceaux prêts", "knowledge.ingestionFailed": "Échec de l'importation pour \"{{name}}\"", "knowledge.loadingChunks": "Chargement des blocs...", "knowledge.loadingKnowledgeBases": "Chargement des bases de connaissances...", + "knowledge.nameLabel": "Nom", + "knowledge.namePlaceholder": "Entrez un nom pour cette base de connaissances", "knowledge.noChunksFound": "Aucun bloc trouvé", "knowledge.noKnowledgeBases": "Pas de base de connaissances", "knowledge.ofTotal": "d' {{total}}", "knowledge.page": "Page", "knowledge.pageTitle": "Connaissances", "knowledge.perPage": "Par page :", + "knowledge.reviewDescription": "Prévisualisez la manière dont vos fichiers seront fractionnés et validez vos paramètres", + "knowledge.reviewTitle": "Analyse et mise en place", "knowledge.searchChunks": "Rechercher des segments...", "knowledge.searchPlaceholder": "Rechercher dans les bases de connaissances...", "knowledge.selected": "{{count}} sélectionné(s)", + "knowledge.separatorLabel": "Séparateur", + "knowledge.separatorTooltip": "Le caractère de séparation. Utilisez \\n pour créer un saut de ligne. Exemples : \\n\\n pour les paragraphes, \\n pour les lignes,. pour les phrases. Ne rien indiquer si vous ne souhaitez pas de séparateur.", "knowledge.showing": "Affichage de {{start}} - {{end}} sur un total de {{total}} segments", + "knowledge.sourcesLabel": "Sources", + "knowledge.submitAddSources": "Ajouter des sources", + "knowledge.submitCreate": "Créer", + "knowledge.successSourcesAdded": "Sources ajoutées à \"{{name}}\"", "knowledge.thisActionCannotBeUndone": "Cette action ne peut pas être annulée", "knowledge.unknownError": "Une erreur inconnue s'est produite", + "knowledge.uploadFiles": "Transférer les fichiers", + "knowledge.uploadFolder": "Dossier de téléchargement", + "knowledge.validationEmbeddingRequired": "Un modèle d'intégration est requis", + "knowledge.validationFileSizeLimit": "La taille totale du fichier dépasse la limite de 1 Go", + "knowledge.validationNameDuplicate": "Une base de connaissances portant ce nom existe déjà", + "knowledge.validationNameFormat": "Le nom doit uniquement contenir [ a-zA-Z0-9._-] et commencer/se terminer par [ a-zA-Z0-9 ]", + "knowledge.validationNameLength": "Le nom doit comporter entre 3 et 512 caractères", + "knowledge.validationNameRequired": "Nom obligatoire", "mainPage.delete": "Supprimer", "mainPage.flowsDeletedSuccess": "Les flux ont été supprimés avec succès", "mainPage.flowsDownloadedSuccess": "Les flux ont été téléchargés avec succès", @@ -485,4 +528,4 @@ "templatesModal.title": "Modèles", "templatesModal.tryDifferentQuery": "et essayez une autre requête.", "templatesModal.useCases": "Cas d'usage" -} +} \ No newline at end of file diff --git a/src/frontend/src/locales/ja.json b/src/frontend/src/locales/ja.json index 7f0d30ed37..11a87d5a22 100644 --- a/src/frontend/src/locales/ja.json +++ b/src/frontend/src/locales/ja.json @@ -160,6 +160,11 @@ "flow.brokenEdgesWarning": "無効な接続がいくつか削除されました:", "flow.buildStatus": "ステータスを確認するためにビルドする。", "flow.buildSuccess": "無事に完成しました ✨", + "flow.duplicatedSuccess": "{{type}} 複製に成功しました", + "flow.menu.delete": "削除", + "flow.menu.duplicate": "重複", + "flow.menu.editDetails": "詳細の編集", + "flow.menu.export": "エクスポート", "flow.missingFields": "必須項目はすべてご記入ください。", "flow.noCompatibleComponents": "互換性のあるコンポーネントが見つかりませんでした。", "flow.runTimestampPrefix": "最終走行: ", @@ -210,30 +215,68 @@ "input.titleErrorUpdatingComponent": "コンポーネントの更新中にエラーが発生しました", "input.toolsetPlaceholder": "道具として使われる", "knowledge.addKnowledge": "知識の追加", + "knowledge.addSources": "ソースの追加", + "knowledge.addSourcesDescription": "ファイルをアップロードし、チャンキング設定を行う", + "knowledge.addSourcesTitle": "ソースの追加", "knowledge.baseCreated": "ナレッジベース「 \"{{name}}\" 」が作成されました", + "knowledge.chunkOverlapLabel": "チャンク重複", + "knowledge.chunkOverlapTooltip": "チャンク間で重なり合わせる文字数。", + "knowledge.chunkSizeLabel": "チャンク・サイズ", + "knowledge.chunkSizeTooltip": "各チャンクの最大長。 テキストはまず区切り文字で分割され、その後、このサイズまでチャンクが結合されます。", + "knowledge.chunkingSettings": "チャンキング設定", + "knowledge.configureSources": "ソースの設定", + "knowledge.configureSourcesMaxSize": "(アップロード上限:1 GB)", + "knowledge.createDescription": "ナレッジベースに名前を付け、ソースをアップロードし、埋め込みモデルを選択してください", + "knowledge.createTitle": "ナレッジベースを作成する", "knowledge.delete": "削除", "knowledge.deleteSelected": "削除 ( {{count}} )", "knowledge.deletedCount": "{{count}} ナレッジベースが削除されました", + "knowledge.embeddingModelLabel": "モデルのエンベッド", + "knowledge.embeddingModelPlaceholder": "埋め込みモデルを選択", + "knowledge.embeddingModelUnknown": "不明", "knowledge.emptyDescription": "ドキュメントをインテリジェントなワークフローと連携させ、強力なAI体験を実現しましょう。", + "knowledge.errorChunkPreview": "チャンクのプレビューの生成に失敗しました", + "knowledge.errorCreateFailed": "ナレッジベースの作成に失敗しました", + "knowledge.errorIngestion": "\"{{name}}\" の取り込みを開始できませんでした", "knowledge.failedToDelete": "ナレッジベースの削除に失敗しました", "knowledge.failedToLoad": "ナレッジベースの読み込みに失敗しました", "knowledge.failedToLoadChunks": "チャンクの読み込みに失敗しました", + "knowledge.helpConfigureSources": "ソースの設定", + "knowledge.helpHideConfiguration": "設定を非表示にする", "knowledge.ingestionComplete": "\"{{name}}\" 取り込み完了 — {{chunks}} チャンクが準備完了", "knowledge.ingestionFailed": "\"{{name}}\" の取り込みに失敗しました", "knowledge.loadingChunks": "チャンクを読み込んでいます...", "knowledge.loadingKnowledgeBases": "ナレッジベースを読み込んでいます...", + "knowledge.nameLabel": "名前", + "knowledge.namePlaceholder": "このナレッジベースの名前を入力してください", "knowledge.noChunksFound": "チャンクが見つかりませんでした", "knowledge.noKnowledgeBases": "ナレッジベースはありません", "knowledge.ofTotal": "{{total}} の", "knowledge.page": "ページ", "knowledge.pageTitle": "ナレッジ", "knowledge.perPage": "1ページあたり:", + "knowledge.reviewDescription": "ファイルがどのように分割されるかを確認し、設定を確定してください", + "knowledge.reviewTitle": "レビューと作成", "knowledge.searchChunks": "チャンクを検索...", "knowledge.searchPlaceholder": "ナレッジベースを検索...", "knowledge.selected": "{{count}} 個を選択済み", + "knowledge.separatorLabel": "分離文字", + "knowledge.separatorTooltip": "分割する文字。 改行には \\n を使用してください。 例:\\n\\n(段落)、\\n(行)、。 文について。 区切り文字を挿入しない場合は、空欄のままにしてください。", "knowledge.showing": "表示中: {{start}} - {{total}} のチャンク {{end}} 個", + "knowledge.sourcesLabel": "ソース", + "knowledge.submitAddSources": "ソースの追加", + "knowledge.submitCreate": "作成", + "knowledge.successSourcesAdded": "\"{{name}}\" に追加された情報源", "knowledge.thisActionCannotBeUndone": "この操作は元に戻せません", "knowledge.unknownError": "不明なエラーが発生しました", + "knowledge.uploadFiles": "ファイルのアップロード", + "knowledge.uploadFolder": "アップロードフォルダ", + "knowledge.validationEmbeddingRequired": "モデルの埋め込みが必要です", + "knowledge.validationFileSizeLimit": "ファイルの合計サイズが1 GBの制限を超えています", + "knowledge.validationNameDuplicate": "この名前のナレッジベースはすでに存在します", + "knowledge.validationNameFormat": "名前には [ a-zA-Z0-9._-] のみを含め、先頭と末尾は [ a-zA-Z0-9 ] でなければならない", + "knowledge.validationNameLength": "名前は3文字以上512文字以下で入力してください", + "knowledge.validationNameRequired": "名前は必須です", "mainPage.delete": "削除", "mainPage.flowsDeletedSuccess": "フローが正常に削除されました", "mainPage.flowsDownloadedSuccess": "データのダウンロードが完了しました", @@ -485,4 +528,4 @@ "templatesModal.title": "テンプレート", "templatesModal.tryDifferentQuery": "別のクエリを試してみてください。", "templatesModal.useCases": "ユースケース" -} +} \ No newline at end of file diff --git a/src/frontend/src/locales/pt.json b/src/frontend/src/locales/pt.json index cab565782a..ce3f9c29db 100644 --- a/src/frontend/src/locales/pt.json +++ b/src/frontend/src/locales/pt.json @@ -160,6 +160,11 @@ "flow.brokenEdgesWarning": "Algumas conexões foram removidas por serem inválidas:", "flow.buildStatus": "Compilar para verificar o status.", "flow.buildSuccess": "Construído com sucesso ✨", + "flow.duplicatedSuccess": "{{type}} duplicado com sucesso", + "flow.menu.delete": "Excluir", + "flow.menu.duplicate": "Duplicata", + "flow.menu.editDetails": "Editar detalhes", + "flow.menu.export": "Exportar", "flow.missingFields": "Preencha todos os campos obrigatórios.", "flow.noCompatibleComponents": "Não foram encontrados componentes compatíveis.", "flow.runTimestampPrefix": "Última corrida: ", @@ -210,30 +215,68 @@ "input.titleErrorUpdatingComponent": "Erro ao atualizar o componente", "input.toolsetPlaceholder": "Usado como ferramenta", "knowledge.addKnowledge": "Incluir conhecimento", + "knowledge.addSources": "Incluir origens", + "knowledge.addSourcesDescription": "Carregue arquivos e configure as opções de fragmentação", + "knowledge.addSourcesTitle": "Incluir origens", "knowledge.baseCreated": "Base de conhecimento \"{{name}}\" criada", + "knowledge.chunkOverlapLabel": "Sobreposição das partes", + "knowledge.chunkOverlapTooltip": "Número de caracteres a serem sobrepostos entre blocos.", + "knowledge.chunkSizeLabel": "Tamanho do chunk", + "knowledge.chunkSizeTooltip": "O comprimento máximo de cada bloco. O texto é primeiro dividido pelo separador e, em seguida, os trechos são agrupados até atingirem esse tamanho.", + "knowledge.chunkingSettings": "Configurações de segmentação", + "knowledge.configureSources": "Configurar fontes", + "knowledge.configureSourcesMaxSize": "(máximo de 1 GB para upload)", + "knowledge.createDescription": "Dê um nome à sua base de conhecimento, carregue as fontes e selecione um modelo de incorporação", + "knowledge.createTitle": "Criar uma base de conhecimento", "knowledge.delete": "Excluir", "knowledge.deleteSelected": "Excluir ( {{count}} )", "knowledge.deletedCount": "{{count}} base(s) de conhecimento excluída(s)", + "knowledge.embeddingModelLabel": "Modelo de integração", + "knowledge.embeddingModelPlaceholder": "Selecionar modelo de incorporação", + "knowledge.embeddingModelUnknown": "Desconhecido", "knowledge.emptyDescription": "Crie experiências de IA poderosas conectando seus documentos a fluxos de trabalho inteligentes.", + "knowledge.errorChunkPreview": "Falha ao gerar a pré-visualização do bloco", + "knowledge.errorCreateFailed": "Falha ao criar a base de conhecimento", + "knowledge.errorIngestion": "Falha ao iniciar a ingestão para \"{{name}}\"", "knowledge.failedToDelete": "Falha ao excluir bases de conhecimento", "knowledge.failedToLoad": "Falha ao carregar as bases de conhecimento", "knowledge.failedToLoadChunks": "Falha ao carregar os blocos", + "knowledge.helpConfigureSources": "Configurar fontes", + "knowledge.helpHideConfiguration": "Ocultar configuração", "knowledge.ingestionComplete": "\"{{name}}\" Ingestão concluída — {{chunks}} blocos prontos", "knowledge.ingestionFailed": "Falha na importação de \"{{name}}\"", "knowledge.loadingChunks": "Carregando blocos...", "knowledge.loadingKnowledgeBases": "Carregando bases de conhecimento...", + "knowledge.nameLabel": "Nome", + "knowledge.namePlaceholder": "Digite um nome para esta base de conhecimento", "knowledge.noChunksFound": "Não foram encontrados blocos", "knowledge.noKnowledgeBases": "Não há bases de conhecimento", "knowledge.ofTotal": "de {{total}}", "knowledge.page": "Página", "knowledge.pageTitle": "Conhecimento", "knowledge.perPage": "Por página:", + "knowledge.reviewDescription": "Visualize como seus arquivos serão divididos em partes e confirme suas configurações", + "knowledge.reviewTitle": "Análise e montagem", "knowledge.searchChunks": "Pesquisar trechos...", "knowledge.searchPlaceholder": "Pesquisar nas bases de conhecimento...", "knowledge.selected": "{{count}} selecionado", + "knowledge.separatorLabel": "Separador", + "knowledge.separatorTooltip": "O caractere no qual a divisão deve ser feita. Use \\n para criar uma nova linha. Exemplos: \\n\\n para parágrafos, \\n para linhas,. para frases. Deixe em branco se não houver separador.", "knowledge.showing": "Exibindo {{start}} - {{end}} de {{total}} blocos", + "knowledge.sourcesLabel": "Origens", + "knowledge.submitAddSources": "Incluir origens", + "knowledge.submitCreate": "Criar", + "knowledge.successSourcesAdded": "Fontes adicionadas ao site \"{{name}}\"", "knowledge.thisActionCannotBeUndone": "Esta ação não pode ser revertida", "knowledge.unknownError": "Ocorreu um erro desconhecido", + "knowledge.uploadFiles": "Fazer upload de arquivos", + "knowledge.uploadFolder": "Carregar pasta", + "knowledge.validationEmbeddingRequired": "É necessário incorporar o modelo", + "knowledge.validationFileSizeLimit": "O tamanho total do arquivo excede o limite de 1 GB", + "knowledge.validationNameDuplicate": "Já existe uma base de conhecimento com esse nome", + "knowledge.validationNameFormat": "O nome deve conter apenas [ a-zA-Z0-9._-] e começar/terminar com [ a-zA-Z0-9 ]", + "knowledge.validationNameLength": "O nome deve ter entre 3 e 512 caracteres", + "knowledge.validationNameRequired": "O nome é obrigatório", "mainPage.delete": "Excluir", "mainPage.flowsDeletedSuccess": "Fluxos excluídos com sucesso", "mainPage.flowsDownloadedSuccess": "Fluxos baixados com sucesso", @@ -485,4 +528,4 @@ "templatesModal.title": "Modelos", "templatesModal.tryDifferentQuery": "e tente uma consulta diferente.", "templatesModal.useCases": "Casos de uso" -} +} \ No newline at end of file diff --git a/src/frontend/src/locales/zh-Hans.json b/src/frontend/src/locales/zh-Hans.json index 98d5a84dfe..30c2bb5ab7 100644 --- a/src/frontend/src/locales/zh-Hans.json +++ b/src/frontend/src/locales/zh-Hans.json @@ -160,6 +160,11 @@ "flow.brokenEdgesWarning": "某些连接已被移除,因为它们无效:", "flow.buildStatus": "构建以验证状态。", "flow.buildSuccess": "已成功构建 ✨", + "flow.duplicatedSuccess": "{{type}} 已成功复制", + "flow.menu.delete": "删除", + "flow.menu.duplicate": "复制", + "flow.menu.editDetails": "编辑详细信息", + "flow.menu.export": "导出", "flow.missingFields": "请填写所有必填项。", "flow.noCompatibleComponents": "未找到兼容的组件。", "flow.runTimestampPrefix": "最后一次运行: ", @@ -210,30 +215,68 @@ "input.titleErrorUpdatingComponent": "更新组件时发生错误", "input.toolsetPlaceholder": "作为一种工具", "knowledge.addKnowledge": "添加知识", + "knowledge.addSources": "添加源", + "knowledge.addSourcesDescription": "上传文件并配置分块设置", + "knowledge.addSourcesTitle": "添加源", "knowledge.baseCreated": "知识库 \"{{name}}\" 已创建", + "knowledge.chunkOverlapLabel": "块重叠", + "knowledge.chunkOverlapTooltip": "各片段之间重叠的字符数。", + "knowledge.chunkSizeLabel": "块大小", + "knowledge.chunkSizeTooltip": "每个数据块的最大长度。 首先按分隔符将文本拆分,然后将各段合并至此大小。", + "knowledge.chunkingSettings": "分块设置", + "knowledge.configureSources": "配置来源", + "knowledge.configureSourcesMaxSize": "(最大上传容量为 1 GB)", + "knowledge.createDescription": "为知识库命名,上传数据源,并选择嵌入模型", + "knowledge.createTitle": "创建知识库", "knowledge.delete": "删除", "knowledge.deleteSelected": "删除 ( {{count}} )", "knowledge.deletedCount": "{{count}} 已删除知识库", + "knowledge.embeddingModelLabel": "嵌入模型", + "knowledge.embeddingModelPlaceholder": "选择嵌入模型", + "knowledge.embeddingModelUnknown": "未知", "knowledge.emptyDescription": "通过将文档与智能工作流相连接,打造强大的 AI 体验。", + "knowledge.errorChunkPreview": "无法生成片段预览", + "knowledge.errorCreateFailed": "无法创建知识库", + "knowledge.errorIngestion": "无法为 \"{{name}}\" 启动数据采集", "knowledge.failedToDelete": "无法删除知识库", "knowledge.failedToLoad": "无法加载知识库", "knowledge.failedToLoadChunks": "无法加载区块", + "knowledge.helpConfigureSources": "配置来源", + "knowledge.helpHideConfiguration": "隐藏配置", "knowledge.ingestionComplete": "\"{{name}}\" 摄入完成 — {{chunks}} 个数据块已准备就绪", "knowledge.ingestionFailed": "无法将 \"{{name}}\" 导入", "knowledge.loadingChunks": "正在加载数据块……", "knowledge.loadingKnowledgeBases": "正在加载知识库...", + "knowledge.nameLabel": "名称", + "knowledge.namePlaceholder": "请为该知识库输入名称", "knowledge.noChunksFound": "未找到任何片段", "knowledge.noKnowledgeBases": "没有知识库", "knowledge.ofTotal": "{{total}}", "knowledge.page": "页面", "knowledge.pageTitle": "知识", "knowledge.perPage": "每页:", + "knowledge.reviewDescription": "预览文件的分块情况并确认设置", + "knowledge.reviewTitle": "评测与组装", "knowledge.searchChunks": "搜索片段...", "knowledge.searchPlaceholder": "搜索知识库...", "knowledge.selected": "已选择 {{count}} 个", + "knowledge.separatorLabel": "分隔符", + "knowledge.separatorTooltip": "用于分割的字符。 使用 \\n 表示换行。 示例:\\n\\n 表示段落,\\n 表示换行,。 用于句子。 若不需分隔符,请留空。", "knowledge.showing": "显示 {{start}} - {{end}} ,共 {{total}} 个片段", + "knowledge.sourcesLabel": "源", + "knowledge.submitAddSources": "添加源", + "knowledge.submitCreate": "创建", + "knowledge.successSourcesAdded": "已将来源添加至 \"{{name}}\"", "knowledge.thisActionCannotBeUndone": "此操作无法撤销", "knowledge.unknownError": "发生了一个未知错误", + "knowledge.uploadFiles": "上传文件", + "knowledge.uploadFolder": "上传文件夹", + "knowledge.validationEmbeddingRequired": "需要嵌入模型", + "knowledge.validationFileSizeLimit": "文件总大小超过了 1 GB 的限制", + "knowledge.validationNameDuplicate": "已经存在一个同名的知识库", + "knowledge.validationNameFormat": "名称必须仅包含 [ a-zA-Z0-9._-],且以 [ a-zA-Z0-9 ] 开头和结尾", + "knowledge.validationNameLength": "名称必须包含3至512个字符", + "knowledge.validationNameRequired": "名称是必需的", "mainPage.delete": "删除", "mainPage.flowsDeletedSuccess": "流程已成功删除", "mainPage.flowsDownloadedSuccess": "流程已成功下载", @@ -485,4 +528,4 @@ "templatesModal.title": "模板", "templatesModal.tryDifferentQuery": "并尝试其他查询。", "templatesModal.useCases": "用例" -} +} \ No newline at end of file diff --git a/src/frontend/src/modals/knowledgeBaseUploadModal/KnowledgeBaseUploadModal.tsx b/src/frontend/src/modals/knowledgeBaseUploadModal/KnowledgeBaseUploadModal.tsx index a77d8d2528..c99bf55529 100644 --- a/src/frontend/src/modals/knowledgeBaseUploadModal/KnowledgeBaseUploadModal.tsx +++ b/src/frontend/src/modals/knowledgeBaseUploadModal/KnowledgeBaseUploadModal.tsx @@ -1,9 +1,10 @@ import { useState } from "react"; +import { useTranslation } from "react-i18next"; import { StepperModal, StepperModalFooter } from "../stepperModal/StepperModal"; import { FilesPanel } from "./components/FilesPanel"; import { StepConfiguration } from "./components/StepConfiguration"; import { StepReview } from "./components/StepReview"; -import { STEP_DESCRIPTIONS, STEP_TITLES } from "./constants"; +import { getStepDescriptions, getStepTitles } from "./constants"; import { useKnowledgeBaseForm } from "./hooks/useKnowledgeBaseForm"; import type { KnowledgeBaseUploadModalProps } from "./types"; @@ -20,6 +21,7 @@ export default function KnowledgeBaseUploadModal({ hideAdvanced, existingKnowledgeBaseNames, }: KnowledgeBaseUploadModalProps) { + const { t } = useTranslation(); const [internalOpen, setInternalOpen] = useState(false); const open = controlledOpen ?? internalOpen; const setOpen = controlledSetOpen ?? setInternalOpen; @@ -96,12 +98,14 @@ export default function KnowledgeBaseUploadModal({ currentStep={form.currentStep} totalSteps={2} title={ - form.isAddSourcesMode ? "Add Sources" : STEP_TITLES[form.currentStep] + form.isAddSourcesMode + ? t("knowledge.addSourcesTitle") + : getStepTitles()[form.currentStep] } description={ form.isAddSourcesMode && form.currentStep === 1 - ? "Upload files and configure chunking settings" - : STEP_DESCRIPTIONS[form.currentStep] + ? t("knowledge.addSourcesDescription") + : getStepDescriptions()[form.currentStep] } icon="Database" height={(() => { @@ -129,12 +133,16 @@ export default function KnowledgeBaseUploadModal({ } isSubmitting={form.isSubmitting} submitTestId="kb-create-button" - submitLabel={form.isAddSourcesMode ? "Add Sources" : "Create"} + submitLabel={ + form.isAddSourcesMode + ? t("knowledge.submitAddSources") + : t("knowledge.submitCreate") + } helpLabel={ !hideAdvanced && form.currentStep === 1 ? form.showAdvanced - ? "Hide Configuration" - : "Configure Sources" + ? t("knowledge.helpHideConfiguration") + : t("knowledge.helpConfigureSources") : undefined } onHelp={ diff --git a/src/frontend/src/modals/knowledgeBaseUploadModal/components/StepConfiguration.tsx b/src/frontend/src/modals/knowledgeBaseUploadModal/components/StepConfiguration.tsx index 59ede6b733..76626cd675 100644 --- a/src/frontend/src/modals/knowledgeBaseUploadModal/components/StepConfiguration.tsx +++ b/src/frontend/src/modals/knowledgeBaseUploadModal/components/StepConfiguration.tsx @@ -1,4 +1,5 @@ import ForwardedIconComponent from "@/components/common/genericIconComponent"; +import { useTranslation } from "react-i18next"; import ModelInputComponent, { type ModelOption, } from "@/components/core/parameterRenderComponent/components/modelInputComponent"; @@ -72,17 +73,18 @@ export function StepConfiguration({ columnConfig, onColumnConfigChange, }: StepConfigurationProps) { + const { t } = useTranslation(); return (
{/* Name */}
{ onSourceNameChange(e.target.value); @@ -102,7 +104,7 @@ export function StepConfiguration({ {/* Model Selection */}
{isAddSourcesMode ? (
@@ -111,7 +113,7 @@ export function StepConfiguration({ className="h-4 w-4 shrink-0" /> - {existingEmbeddingModel || "Unknown"} + {existingEmbeddingModel || t("knowledge.embeddingModelUnknown")}
) : ( @@ -132,7 +134,7 @@ export function StepConfiguration({ onFieldChange?.(); }} options={embeddingModelOptions} - placeholder="Select embedding model" + placeholder={t("knowledge.embeddingModelPlaceholder")} showEmptyState />
@@ -184,9 +186,9 @@ export function StepConfiguration({ className="h-4 w-4 text-muted-foreground" /> - Configure Sources + {t("knowledge.configureSources")} - (1 GB max upload) + {t("knowledge.configureSourcesMaxSize")}
@@ -194,7 +196,7 @@ export function StepConfiguration({
@@ -211,7 +213,7 @@ export function StepConfiguration({ name="Upload" className="h-4 w-4" /> - Add Sources + {t("knowledge.addSources")} - Upload Files + {t("knowledge.uploadFiles")} @@ -240,7 +242,7 @@ export function StepConfiguration({ name="Folder" className="mr-2 h-4 w-4" /> - Upload Folder + {t("knowledge.uploadFolder")} @@ -297,7 +299,7 @@ export function StepConfiguration({ name="Settings2" className="h-4 w-4 text-muted-foreground" /> - Chunking Settings + {t("knowledge.chunkingSettings")}
@@ -307,7 +309,7 @@ export function StepConfiguration({ htmlFor="chunk-size" className="flex items-center gap-1 text-xs text-muted-foreground" > - Chunk Size + {t("knowledge.chunkSizeLabel")} @@ -319,8 +321,7 @@ export function StepConfiguration({ - The maximum length of each chunk. Text is first split - by separator, then chunks are merged up to this size. + {t("knowledge.chunkSizeTooltip")} @@ -344,7 +345,7 @@ export function StepConfiguration({ htmlFor="chunk-overlap" className="flex items-center gap-1 text-xs text-muted-foreground" > - Chunk Overlap + {t("knowledge.chunkOverlapLabel")} @@ -356,7 +357,7 @@ export function StepConfiguration({ - Number of characters to overlap between chunks. + {t("knowledge.chunkOverlapTooltip")} @@ -381,7 +382,7 @@ export function StepConfiguration({ htmlFor="separator" className="flex items-center gap-1 text-xs text-muted-foreground" > - Separator + {t("knowledge.separatorLabel")} @@ -393,9 +394,7 @@ export function StepConfiguration({ - The character to split on. Use \n for newline. Examples: - \n\n for paragraphs, \n for lines, . for sentences. - Leave blank for no separator. + {t("knowledge.separatorTooltip")} diff --git a/src/frontend/src/modals/knowledgeBaseUploadModal/constants.ts b/src/frontend/src/modals/knowledgeBaseUploadModal/constants.ts index ad17d59161..e4b48901d4 100644 --- a/src/frontend/src/modals/knowledgeBaseUploadModal/constants.ts +++ b/src/frontend/src/modals/knowledgeBaseUploadModal/constants.ts @@ -1,14 +1,15 @@ +import i18n from "@/i18n"; import type { WizardStep } from "./types"; -export const STEP_TITLES: Record = { - 1: "Create Knowledge Base", - 2: "Review & Build", -}; +export const getStepTitles = (): Record => ({ + 1: i18n.t("knowledge.createTitle"), + 2: i18n.t("knowledge.reviewTitle"), +}); -export const STEP_DESCRIPTIONS: Record = { - 1: "Name your knowledge base, upload sources, and select an embedding model", - 2: "Preview how your files will be chunked and confirm your settings", -}; +export const getStepDescriptions = (): Record => ({ + 1: i18n.t("knowledge.createDescription"), + 2: i18n.t("knowledge.reviewDescription"), +}); export const DEFAULT_CHUNK_SIZE = 100; export const DEFAULT_CHUNK_OVERLAP = 0; diff --git a/src/frontend/src/modals/knowledgeBaseUploadModal/hooks/useKnowledgeBaseForm.ts b/src/frontend/src/modals/knowledgeBaseUploadModal/hooks/useKnowledgeBaseForm.ts index 1c390dd35c..4527555b68 100644 --- a/src/frontend/src/modals/knowledgeBaseUploadModal/hooks/useKnowledgeBaseForm.ts +++ b/src/frontend/src/modals/knowledgeBaseUploadModal/hooks/useKnowledgeBaseForm.ts @@ -1,5 +1,6 @@ import { type AxiosError } from "axios"; import { useCallback, useEffect, useMemo, useState } from "react"; +import { useTranslation } from "react-i18next"; import type { ModelOption } from "@/components/core/parameterRenderComponent/components/modelInputComponent"; import { api } from "@/controllers/API/api"; import { getURL } from "@/controllers/API/helpers/constants"; @@ -39,6 +40,7 @@ export function useKnowledgeBaseForm({ | "hideAdvanced" | "existingKnowledgeBaseNames" >) { + const { t } = useTranslation(); const isAddSourcesMode = !!existingKnowledgeBase; // Wizard state @@ -255,7 +257,7 @@ export function useKnowledgeBaseForm({ } catch (error: unknown) { const err = error as AxiosError<{ detail?: string }>; setErrorData({ - title: "Failed to generate chunk preview", + title: t("knowledge.errorChunkPreview"), list: [err?.response?.data?.detail || err?.message || "Unknown error"], }); setChunkPreviews([]); @@ -275,29 +277,29 @@ export function useKnowledgeBaseForm({ const errors: Record = {}; const trimmedName = sourceName.trim().replace(/\s+/g, "_"); if (!trimmedName) { - errors.sourceName = "Name is required"; + errors.sourceName = t("knowledge.validationNameRequired"); } else if (trimmedName.length < 3 || trimmedName.length > 512) { - errors.sourceName = "Name must be between 3 and 512 characters"; + errors.sourceName = t("knowledge.validationNameLength"); } else if (!KB_NAME_REGEX.test(trimmedName)) { - errors.sourceName = - "Name must only contain [a-zA-Z0-9._-] and start/end with [a-zA-Z0-9]"; + errors.sourceName = t("knowledge.validationNameFormat"); } else if ( !isAddSourcesMode && existingKnowledgeBaseNames?.some( (name) => name.toLowerCase() === trimmedName.toLowerCase(), ) ) { - errors.sourceName = "A knowledge base with this name already exists"; + errors.sourceName = t("knowledge.validationNameDuplicate"); } if (!isAddSourcesMode && selectedEmbeddingModel.length === 0) { - errors.embeddingModel = "Embedding model is required"; + errors.embeddingModel = t("knowledge.validationEmbeddingRequired"); } const totalBytes = files.reduce((acc, file) => acc + file.size, 0); if (totalBytes > MAX_TOTAL_FILE_SIZE) { - errors.files = "Total file size exceeds the 1 GB limit"; + errors.files = t("knowledge.validationFileSizeLimit"); } return errors; }, [ + t, sourceName, isAddSourcesMode, selectedEmbeddingModel, @@ -370,7 +372,7 @@ export function useKnowledgeBaseForm({ .catch((ingestError: unknown) => { const err = ingestError as AxiosError<{ detail?: string }>; setErrorData({ - title: `Failed to start ingestion for "${sourceName}"`, + title: t("knowledge.errorIngestion", { name: sourceName }), list: [ err?.response?.data?.detail || err?.message || "Unknown error", ], @@ -390,11 +392,11 @@ export function useKnowledgeBaseForm({ if (isAddSourcesMode) { setSuccessData({ - title: `Sources added to "${sourceName}"`, + title: t("knowledge.successSourcesAdded", { name: sourceName }), }); } else { setSuccessData({ - title: `Knowledge base "${sourceName}" created`, + title: t("knowledge.baseCreated", { name: sourceName }), }); } @@ -406,7 +408,7 @@ export function useKnowledgeBaseForm({ const errorMessage = err?.response?.data?.detail || err?.message || - "Failed to create knowledge base"; + t("knowledge.errorCreateFailed"); setErrorData({ title: errorMessage }); } finally { setIsSubmitting(false); diff --git a/src/frontend/src/pages/MainPage/components/dropdown/index.tsx b/src/frontend/src/pages/MainPage/components/dropdown/index.tsx index 7e7f64109b..ca6db546b9 100644 --- a/src/frontend/src/pages/MainPage/components/dropdown/index.tsx +++ b/src/frontend/src/pages/MainPage/components/dropdown/index.tsx @@ -2,6 +2,7 @@ import ForwardedIconComponent from "@/components/common/genericIconComponent"; import { DropdownMenuItem } from "@/components/ui/dropdown-menu"; import useAlertStore from "@/stores/alertStore"; import type { FlowType } from "@/types/flow"; +import { useTranslation } from "react-i18next"; import useDuplicateFlow from "../../hooks/use-handle-duplicate"; import useSelectOptionsChange from "../../hooks/use-select-options-change"; @@ -18,6 +19,7 @@ const DropdownComponent = ({ handleExport, handleEdit, }: DropdownComponentProps) => { + const { t } = useTranslation(); const setSuccessData = useAlertStore((state) => state.setSuccessData); const setErrorData = useAlertStore((state) => state.setErrorData); const { handleDuplicate } = useDuplicateFlow({ flow: flowData }); @@ -25,7 +27,9 @@ const DropdownComponent = ({ const duplicateFlow = () => { handleDuplicate().then(() => setSuccessData({ - title: `${flowData.is_component ? "Component" : "Flow"} duplicated successfully`, + title: t("flow.duplicatedSuccess", { + type: flowData.is_component ? "Component" : "Flow", + }), }), ); }; @@ -54,7 +58,7 @@ const DropdownComponent = ({ aria-hidden="true" className="mr-2 h-4 w-4" /> - Edit details + {t("flow.menu.editDetails")} { @@ -69,7 +73,7 @@ const DropdownComponent = ({ aria-hidden="true" className="mr-2 h-4 w-4" /> - Export + {t("flow.menu.export")} { @@ -84,7 +88,7 @@ const DropdownComponent = ({ aria-hidden="true" className="mr-2 h-4 w-4" /> - Duplicate + {t("flow.menu.duplicate")} { @@ -99,7 +103,7 @@ const DropdownComponent = ({ aria-hidden="true" className="mr-2 h-4 w-4" /> - Delete + {t("flow.menu.delete")} );