From ce5a6b4092c656b85b9bea97905db5b92bfecb87 Mon Sep 17 00:00:00 2001 From: RamGopalSrikar Date: Mon, 13 Apr 2026 15:08:42 -0400 Subject: [PATCH] feat(i18n): translate delete confirmation modal and fix CTA button overflow - Translate DeleteConfirmationModal (title, body, buttons, "can't be undone") - Translate flow/folder/component description labels via use-description-modal - Translate "and its message history" and folder delete note at call sites - Fix empty page CTA button overflow with whitespace-normal w-auto Co-Authored-By: Claude Sonnet 4.6 --- src/frontend/src/locales/de.json | 15 +++++++ src/frontend/src/locales/en.json | 17 +++++++- src/frontend/src/locales/es.json | 15 +++++++ src/frontend/src/locales/fr.json | 15 +++++++ src/frontend/src/locales/ja.json | 15 +++++++ src/frontend/src/locales/pt.json | 15 +++++++ src/frontend/src/locales/zh-Hans.json | 15 +++++++ .../modals/deleteConfirmationModal/index.tsx | 22 +++++++--- .../pages/MainPage/components/list/index.tsx | 4 +- .../components/modalsComponent/index.tsx | 43 +++++++++++-------- .../MainPage/hooks/use-description-modal.ts | 17 +++++--- .../src/pages/MainPage/pages/empty-page.tsx | 2 +- 12 files changed, 160 insertions(+), 35 deletions(-) diff --git a/src/frontend/src/locales/de.json b/src/frontend/src/locales/de.json index 4f013b54e2..0984cf2804 100644 --- a/src/frontend/src/locales/de.json +++ b/src/frontend/src/locales/de.json @@ -72,6 +72,21 @@ "component.selectOption": "Auswahl einer Option", "component.updateError": "Beim Aktualisieren der Komponente ist ein unerwarteter Fehler aufgetreten. Wiederholen Sie bitte den Vorgang.", "component.updateErrorTitle": "Fehler beim Aktualisieren der Komponente", + "deleteModal.body": "Dadurch wird die Datei „ {{description}} “ endgültig gelöscht.", + "deleteModal.bodyWithNote": "Dadurch wird die Seite „ {{description}} “ unter {{note}} endgültig gelöscht.", + "deleteModal.cancel": "Abbrechen", + "deleteModal.cannotBeUndone": "Das lässt sich nicht rückgängig machen.", + "deleteModal.component": "Komponente", + "deleteModal.components": "Komponenten von", + "deleteModal.delete": "Löschen", + "deleteModal.flow": "Fluss", + "deleteModal.flows": "Flüsse", + "deleteModal.folder": "Ordner", + "deleteModal.item": "Position", + "deleteModal.items": "Positionen", + "deleteModal.noteFolderContents": "sowie alle damit verbundenen Abläufe und Komponenten", + "deleteModal.noteMessageHistory": "und den Nachrichtenverlauf", + "deleteModal.title": "Löschen", "dialog.chat": "Kommuniziere mit deiner KI. Überwachen Sie Eingänge, Ausgänge und Speicher.", "dialog.code": "Exportieren Sie Ihren Flow, um ihn mithilfe dieses Codes zu integrieren.", "dialog.codeDict": "Passen Sie Ihr Wörterbuch an, indem Sie nach Bedarf Schlüssel-Wert-Paare hinzufügen oder bearbeiten. Unterstützt das Hinzufügen neuer Objekte {} oder Arrays [].", diff --git a/src/frontend/src/locales/en.json b/src/frontend/src/locales/en.json index 8ede13c797..e3a8a8da07 100644 --- a/src/frontend/src/locales/en.json +++ b/src/frontend/src/locales/en.json @@ -469,5 +469,20 @@ "files.columnName": "Name", "files.columnType": "Type", "files.columnSize": "Size", - "files.columnModified": "Modified" + "files.columnModified": "Modified", + "deleteModal.title": "Delete", + "deleteModal.body": "This will permanently delete the {{description}}.", + "deleteModal.bodyWithNote": "This will permanently delete the {{description}} {{note}}.", + "deleteModal.cannotBeUndone": "This can't be undone.", + "deleteModal.cancel": "Cancel", + "deleteModal.delete": "Delete", + "deleteModal.flow": "flow", + "deleteModal.flows": "flows", + "deleteModal.component": "component", + "deleteModal.components": "components", + "deleteModal.item": "item", + "deleteModal.items": "items", + "deleteModal.folder": "folder", + "deleteModal.noteMessageHistory": "and its message history", + "deleteModal.noteFolderContents": "and all associated flows and components" } diff --git a/src/frontend/src/locales/es.json b/src/frontend/src/locales/es.json index f09a49026c..57d25e6049 100644 --- a/src/frontend/src/locales/es.json +++ b/src/frontend/src/locales/es.json @@ -72,6 +72,21 @@ "component.selectOption": "Seleccione una opción", "component.updateError": "Se ha producido un error inesperado al actualizar el componente. Inténtelo de nuevo.", "component.updateErrorTitle": "Se ha producido un error al actualizar el componente", + "deleteModal.body": "Esto eliminará definitivamente el archivo « {{description}} ».", + "deleteModal.bodyWithNote": "Esto eliminará definitivamente el archivo {{description}} {{note}}.", + "deleteModal.cancel": "Cancelar", + "deleteModal.cannotBeUndone": "Esto ya no tiene vuelta atrás.", + "deleteModal.component": "componente", + "deleteModal.components": "componentes", + "deleteModal.delete": "Suprimir", + "deleteModal.flow": "flujo", + "deleteModal.flows": "flujos", + "deleteModal.folder": "carpeta", + "deleteModal.item": "elemento", + "deleteModal.items": "Elementos", + "deleteModal.noteFolderContents": "y todos los flujos y componentes asociados", + "deleteModal.noteMessageHistory": "y su historial de mensajes", + "deleteModal.title": "Suprimir", "dialog.chat": "Interactúa con tu IA. Supervisa las entradas, las salidas y las memorias.", "dialog.code": "Exporta tu flujo para integrarlo utilizando este código.", "dialog.codeDict": "Personaliza tu diccionario añadiendo o editando pares clave-valor según sea necesario. Permite añadir nuevos objetos {} o matrices [].", diff --git a/src/frontend/src/locales/fr.json b/src/frontend/src/locales/fr.json index dd22fad98c..b226410b0d 100644 --- a/src/frontend/src/locales/fr.json +++ b/src/frontend/src/locales/fr.json @@ -72,6 +72,21 @@ "component.selectOption": "Sélectionnez une option", "component.updateError": "Une erreur inattendue s'est produite lors de la mise à jour du composant. Faites une nouvelle tentative.", "component.updateErrorTitle": "Erreur lors de la mise à jour du composant", + "deleteModal.body": "Cela supprimera définitivement l' {{description}}.", + "deleteModal.bodyWithNote": "Cela supprimera définitivement l' {{description}} {{note}}.", + "deleteModal.cancel": "Annuler", + "deleteModal.cannotBeUndone": "C'est irréversible.", + "deleteModal.component": "composant", + "deleteModal.components": "composants", + "deleteModal.delete": "Supprimer", + "deleteModal.flow": "flux", + "deleteModal.flows": "flux", + "deleteModal.folder": "dossier", + "deleteModal.item": "élément", + "deleteModal.items": "éléments", + "deleteModal.noteFolderContents": "ainsi que tous les flux et composants associés", + "deleteModal.noteMessageHistory": "et l'historique de ses messages", + "deleteModal.title": "Supprimer", "dialog.chat": "Interagissez avec votre IA. Surveiller les entrées, les sorties et les mémoires.", "dialog.code": "Exportez votre flux pour l'intégrer à l'aide de ce code.", "dialog.codeDict": "Personnalisez votre dictionnaire en ajoutant ou en modifiant des paires clé-valeur selon vos besoins. Permet d'ajouter de nouveaux objets {} ou tableaux [].", diff --git a/src/frontend/src/locales/ja.json b/src/frontend/src/locales/ja.json index ae20fac759..7f0d30ed37 100644 --- a/src/frontend/src/locales/ja.json +++ b/src/frontend/src/locales/ja.json @@ -72,6 +72,21 @@ "component.selectOption": "オプションを選択", "component.updateError": "コンポーネントの更新中に予期せぬエラーが発生しました。 再試行してください。", "component.updateErrorTitle": "コンポーネントの更新中にエラーが発生しました", + "deleteModal.body": "これにより、 {{description}} が完全に削除されます。", + "deleteModal.bodyWithNote": "これにより、 {{description}} {{note}} が完全に削除されます。", + "deleteModal.cancel": "キャンセル", + "deleteModal.cannotBeUndone": "これは取り消すことができません。", + "deleteModal.component": "コンポーネント", + "deleteModal.components": "コンポーネント", + "deleteModal.delete": "削除", + "deleteModal.flow": "フロー", + "deleteModal.flows": "フロー", + "deleteModal.folder": "フォルダー", + "deleteModal.item": "項目", + "deleteModal.items": "項目", + "deleteModal.noteFolderContents": "および関連するすべてのフローとコンポーネント", + "deleteModal.noteMessageHistory": "およびそのメッセージ履歴", + "deleteModal.title": "削除", "dialog.chat": "AIと対話しましょう。 入力、出力、およびメモリを監視する。", "dialog.code": "このコードを使用して、フローをエクスポートし、統合してください。", "dialog.codeDict": "必要に応じてキーと値のペアを追加・編集し、辞書をカスタマイズしてください。 新しいオブジェクト {} や配列 [] の追加に対応しています。", diff --git a/src/frontend/src/locales/pt.json b/src/frontend/src/locales/pt.json index c97d537a24..cab565782a 100644 --- a/src/frontend/src/locales/pt.json +++ b/src/frontend/src/locales/pt.json @@ -72,6 +72,21 @@ "component.selectOption": "Selecionar uma opção", "component.updateError": "Ocorreu um erro inesperado durante a atualização do componente. Tente novamente.", "component.updateErrorTitle": "Erro ao atualizar o componente", + "deleteModal.body": "Isso excluirá definitivamente o arquivo {{description}}.", + "deleteModal.bodyWithNote": "Isso excluirá definitivamente o arquivo {{description}} {{note}}.", + "deleteModal.cancel": "Cancelar", + "deleteModal.cannotBeUndone": "Isso não tem como ser desfeito.", + "deleteModal.component": "componente", + "deleteModal.components": "Componentes do", + "deleteModal.delete": "Excluir", + "deleteModal.flow": "fluxo", + "deleteModal.flows": "fluxos", + "deleteModal.folder": "pasta", + "deleteModal.item": "item", + "deleteModal.items": "itens", + "deleteModal.noteFolderContents": "e todos os fluxos e componentes associados", + "deleteModal.noteMessageHistory": "e seu histórico de mensagens", + "deleteModal.title": "Excluir", "dialog.chat": "Interaja com sua IA. Monitore entradas, saídas e memórias.", "dialog.code": "Exporte seu fluxo para integrá-lo usando este código.", "dialog.codeDict": "Personalize seu dicionário, adicionando ou editando pares chave-valor conforme necessário. Suporta a adição de novos objetos {} ou matrizes [].", diff --git a/src/frontend/src/locales/zh-Hans.json b/src/frontend/src/locales/zh-Hans.json index e6374cbfb4..98d5a84dfe 100644 --- a/src/frontend/src/locales/zh-Hans.json +++ b/src/frontend/src/locales/zh-Hans.json @@ -72,6 +72,21 @@ "component.selectOption": "选择一个选项", "component.updateError": "更新组件时发生了一个意外错误。 请重试。", "component.updateErrorTitle": "更新组件时发生错误", + "deleteModal.body": "这将永久删除 {{description}}。", + "deleteModal.bodyWithNote": "这将永久删除 {{description}} {{note}}。", + "deleteModal.cancel": "取消", + "deleteModal.cannotBeUndone": "这无法挽回。", + "deleteModal.component": "组件", + "deleteModal.components": "组件", + "deleteModal.delete": "删除", + "deleteModal.flow": "流", + "deleteModal.flows": "流", + "deleteModal.folder": "文件夹", + "deleteModal.item": "项", + "deleteModal.items": "项", + "deleteModal.noteFolderContents": "以及所有相关的流程和组件", + "deleteModal.noteMessageHistory": "及其消息记录", + "deleteModal.title": "删除", "dialog.chat": "与您的 AI 互动。 监控输入、输出和存储器。", "dialog.code": "使用此代码导出您的流程以进行集成。", "dialog.codeDict": "自定义您的字典,根据需要添加或编辑键值对。 支持添加新的对象 {} 或数组 []。", diff --git a/src/frontend/src/modals/deleteConfirmationModal/index.tsx b/src/frontend/src/modals/deleteConfirmationModal/index.tsx index dd80cd6a59..01366c2aaf 100644 --- a/src/frontend/src/modals/deleteConfirmationModal/index.tsx +++ b/src/frontend/src/modals/deleteConfirmationModal/index.tsx @@ -1,5 +1,6 @@ import { DialogClose } from "@radix-ui/react-dialog"; import { Trash2 } from "lucide-react"; +import { useTranslation } from "react-i18next"; import { Button } from "../../components/ui/button"; import { Dialog, @@ -27,6 +28,8 @@ export default function DeleteConfirmationModal({ setOpen?: (open: boolean) => void; note?: string; }) { + const { t } = useTranslation(); + return ( @@ -40,15 +43,22 @@ export default function DeleteConfirmationModal({ className="h-6 w-6 pr-1 text-foreground" strokeWidth={1.5} /> - Delete + {t("deleteModal.title")} - This will permanently delete the {description ?? "flow"} - {note ? " " + note : ""}.
+ {note + ? t("deleteModal.bodyWithNote", { + description: description ?? t("deleteModal.flow"), + note, + }) + : t("deleteModal.body", { + description: description ?? t("deleteModal.flow"), + })}
- This can't be undone. +
+ {t("deleteModal.cannotBeUndone")}
@@ -58,7 +68,7 @@ export default function DeleteConfirmationModal({ variant="outline" data-testid="btn_cancel_delete_confirmation_modal" > - Cancel + {t("deleteModal.cancel")} @@ -70,7 +80,7 @@ export default function DeleteConfirmationModal({ }} data-testid="btn_delete_delete_confirmation_modal" > - Delete + {t("deleteModal.delete")} diff --git a/src/frontend/src/pages/MainPage/components/list/index.tsx b/src/frontend/src/pages/MainPage/components/list/index.tsx index 2b1cba7847..f6eb31cccf 100644 --- a/src/frontend/src/pages/MainPage/components/list/index.tsx +++ b/src/frontend/src/pages/MainPage/components/list/index.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; import { useParams } from "react-router-dom"; import ForwardedIconComponent from "@/components/common/genericIconComponent"; import useDragStart from "@/components/core/cardComponent/hooks/use-on-drag-start"; @@ -36,6 +37,7 @@ const ListComponent = ({ setSelected: (selected: boolean) => void; shiftPressed: boolean; }) => { + const { t } = useTranslation(); const navigate = useCustomNavigate(); const [openDelete, setOpenDelete] = useState(false); const setSuccessData = useAlertStore((state) => state.setSuccessData); @@ -216,7 +218,7 @@ const ListComponent = ({ setOpen={setOpenDelete} onConfirm={handleDelete} description={descriptionModal} - note={!flowData.is_component ? "and its message history" : ""} + note={!flowData.is_component ? t("deleteModal.noteMessageHistory") : ""} /> )} {}, handleDeleteFolder = () => {}, -}: ModalsProps) => ( - <> - {openModal && } - {openDeleteFolderModal && ( - { - handleDeleteFolder(); - setOpenDeleteFolderModal(false); - }} - description="folder" - note={"and all associated flows and components"} - > - <> - - )} - -); +}: ModalsProps) => { + const { t } = useTranslation(); + + return ( + <> + {openModal && } + {openDeleteFolderModal && ( + { + handleDeleteFolder(); + setOpenDeleteFolderModal(false); + }} + description={t("deleteModal.folder")} + note={t("deleteModal.noteFolderContents")} + > + <> + + )} + + ); +}; export default ModalsComponent; diff --git a/src/frontend/src/pages/MainPage/hooks/use-description-modal.ts b/src/frontend/src/pages/MainPage/hooks/use-description-modal.ts index 2af71e91a2..d8f0c48eba 100644 --- a/src/frontend/src/pages/MainPage/hooks/use-description-modal.ts +++ b/src/frontend/src/pages/MainPage/hooks/use-description-modal.ts @@ -1,24 +1,27 @@ import { useMemo } from "react"; +import { useTranslation } from "react-i18next"; const useDescriptionModal = ( selectedFlowsComponentsCards: string[] | undefined, type: string | undefined, ) => { + const { t } = useTranslation(); + const getDescriptionModal = useMemo(() => { const getTypeLabel = (type) => { const labels = { - all: "item", - component: "component", - flow: "flow", + all: t("deleteModal.item"), + component: t("deleteModal.component"), + flow: t("deleteModal.flow"), }; return labels[type] || ""; }; const getPluralizedLabel = (type) => { const labels = { - all: "items", - component: "components", - flow: "flows", + all: t("deleteModal.items"), + component: t("deleteModal.components"), + flow: t("deleteModal.flows"), }; return labels[type] || ""; }; @@ -27,7 +30,7 @@ const useDescriptionModal = ( return getTypeLabel(type); } return getPluralizedLabel(type); - }, [selectedFlowsComponentsCards, type]); + }, [selectedFlowsComponentsCards, type, t]); return getDescriptionModal; }; diff --git a/src/frontend/src/pages/MainPage/pages/empty-page.tsx b/src/frontend/src/pages/MainPage/pages/empty-page.tsx index 8ed8826938..a0f45701a5 100644 --- a/src/frontend/src/pages/MainPage/pages/empty-page.tsx +++ b/src/frontend/src/pages/MainPage/pages/empty-page.tsx @@ -154,7 +154,7 @@ export const EmptyPageCommunity = ({