From d69efffd5451c81de80a8e97558cb6ac6ae54797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alcib=C3=ADades=20Cabral=20D=C3=ADaz?= <62911544+alcibiadesc@users.noreply.github.com> Date: Mon, 22 Sep 2025 18:21:05 +0100 Subject: [PATCH] Add Spanish (ES) language support to i18n system (#795) * Add Spanish (ES) language support to i18n system - Added Es variant to UiLanguage enum in Rust backend - Regenerated TypeScript types to include Spanish support - Created complete Spanish translation files for all UI components - Updated i18n configuration to include Spanish resources - Added Spanish option to language selector in settings - Updated existing language files to include Spanish in options All major UI areas now support Spanish including navigation, settings, project management, and status messages. * Fix formatting for Spanish translation files Run Prettier to ensure consistent JSON formatting --- .../src/services/config/versions/v6.rs | 1 + frontend/src/i18n/config.ts | 8 + frontend/src/i18n/locales/en/common.json | 1 + frontend/src/i18n/locales/es/common.json | 26 +++ frontend/src/i18n/locales/es/projects.json | 14 ++ frontend/src/i18n/locales/es/settings.json | 171 ++++++++++++++++++ frontend/src/i18n/locales/ja/common.json | 1 + .../src/pages/settings/GeneralSettings.tsx | 3 + shared/types.ts | 2 +- 9 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 frontend/src/i18n/locales/es/common.json create mode 100644 frontend/src/i18n/locales/es/projects.json create mode 100644 frontend/src/i18n/locales/es/settings.json diff --git a/crates/services/src/services/config/versions/v6.rs b/crates/services/src/services/config/versions/v6.rs index 72f74943..ec9aea5c 100644 --- a/crates/services/src/services/config/versions/v6.rs +++ b/crates/services/src/services/config/versions/v6.rs @@ -17,6 +17,7 @@ pub enum UiLanguage { Browser, // Detect from browser En, // Force English Ja, // Force Japanese + Es, // Force Spanish } #[derive(Clone, Debug, Serialize, Deserialize, TS)] diff --git a/frontend/src/i18n/config.ts b/frontend/src/i18n/config.ts index be79668b..a47777d8 100644 --- a/frontend/src/i18n/config.ts +++ b/frontend/src/i18n/config.ts @@ -9,6 +9,9 @@ import enProjects from './locales/en/projects.json'; import jaCommon from './locales/ja/common.json'; import jaSettings from './locales/ja/settings.json'; import jaProjects from './locales/ja/projects.json'; +import esCommon from './locales/es/common.json'; +import esSettings from './locales/es/settings.json'; +import esProjects from './locales/es/projects.json'; const resources = { en: { @@ -21,6 +24,11 @@ const resources = { settings: jaSettings, projects: jaProjects, }, + es: { + common: esCommon, + settings: esSettings, + projects: esProjects, + }, }; i18n diff --git a/frontend/src/i18n/locales/en/common.json b/frontend/src/i18n/locales/en/common.json index 4c1efd5a..08786a32 100644 --- a/frontend/src/i18n/locales/en/common.json +++ b/frontend/src/i18n/locales/en/common.json @@ -20,6 +20,7 @@ "language": { "en": "English", "ja": "日本語", + "es": "Español", "browserDefault": "Browser Default" }, "conversation": { diff --git a/frontend/src/i18n/locales/es/common.json b/frontend/src/i18n/locales/es/common.json new file mode 100644 index 00000000..e10a07ac --- /dev/null +++ b/frontend/src/i18n/locales/es/common.json @@ -0,0 +1,26 @@ +{ + "buttons": { + "save": "Guardar", + "cancel": "Cancelar", + "delete": "Eliminar", + "edit": "Editar", + "create": "Crear", + "continue": "Continuar", + "reset": "Restablecer", + "manage": "Gestionar", + "connect": "Conectar", + "disconnect": "Desconectar" + }, + "states": { + "loading": "Cargando...", + "saving": "Guardando...", + "error": "Error", + "success": "Éxito" + }, + "language": { + "en": "English", + "ja": "日本語", + "es": "Español", + "browserDefault": "Predeterminado del navegador" + } +} diff --git a/frontend/src/i18n/locales/es/projects.json b/frontend/src/i18n/locales/es/projects.json new file mode 100644 index 00000000..f07209fa --- /dev/null +++ b/frontend/src/i18n/locales/es/projects.json @@ -0,0 +1,14 @@ +{ + "title": "Proyectos", + "subtitle": "Gestiona tus proyectos y sigue su progreso", + "createProject": "Crear Proyecto", + "loading": "Cargando proyectos...", + "errors": { + "fetchFailed": "Error al cargar proyectos" + }, + "empty": { + "title": "Aún no hay proyectos", + "description": "Comienza creando tu primer proyecto.", + "createFirst": "Crear tu primer proyecto" + } +} diff --git a/frontend/src/i18n/locales/es/settings.json b/frontend/src/i18n/locales/es/settings.json new file mode 100644 index 00000000..893ee960 --- /dev/null +++ b/frontend/src/i18n/locales/es/settings.json @@ -0,0 +1,171 @@ +{ + "settings": { + "layout": { + "nav": { + "title": "Configuración", + "general": "General", + "generalDesc": "Tema, notificaciones y preferencias", + "agents": "Agentes", + "agentsDesc": "Configuraciones de agentes", + "mcp": "Servidores MCP", + "mcpDesc": "Servidores de Protocolo de Contexto de Modelo (MCP)" + } + }, + "general": { + "loading": "Cargando configuración...", + "loadError": "Error al cargar la configuración.", + "save": { + "button": "Guardar Configuración", + "success": "✓ ¡Configuración guardada!", + "error": "Error al guardar la configuración" + }, + "appearance": { + "title": "Apariencia", + "description": "Personaliza cómo se ve la aplicación.", + "theme": { + "label": "Tema", + "placeholder": "Seleccionar tema", + "helper": "Elige tus colores preferidos." + }, + "language": { + "label": "Idioma", + "placeholder": "Selecciona tu idioma", + "helper": "Elige tu idioma preferido. El predeterminado del navegador sigue el idioma de tu sistema." + } + }, + "taskExecution": { + "title": "Ejecución de Tareas", + "description": "Configura cómo se ejecutan y procesan las tareas.", + "executor": { + "label": "Configuración predeterminada del Agente", + "placeholder": "Seleccionar perfil", + "helper": "Define la configuración predeterminada del agente que se usará al iniciar una tarea." + }, + "variant": "PREDETERMINADO" + }, + "editor": { + "title": "Editor", + "description": "Configura cómo quieres editar tu código.", + "type": { + "label": "Tipo de Editor", + "placeholder": "Seleccionar editor", + "helper": "Elige tu editor de código preferido." + } + }, + "github": { + "title": "Integración con GitHub", + "connected": "Conectado como {{username}}", + "connectButton": "Conectar Cuenta de GitHub", + "manage": "Gestionar", + "disconnect": "Desconectar", + "helper": "Conecta tu cuenta de GitHub para acceder a repositorios privados y habilitar acciones avanzadas de Git." + }, + "notifications": { + "title": "Notificaciones", + "description": "Controla cuándo y cómo recibes notificaciones.", + "sound": { + "label": "Notificaciones de Sonido", + "helper": "Reproduce un sonido cuando una tarea termina de ejecutarse.", + "fileLabel": "Sonido", + "filePlaceholder": "Seleccionar sonido", + "fileHelper": "Elige el sonido que se reproducirá al completar las tareas. Haz clic en el botón de volumen para escucharlo." + }, + "push": { + "label": "Notificaciones Push", + "helper": "Muestra notificaciones del sistema cuando las tareas terminan de ejecutarse." + } + }, + "privacy": { + "title": "Privacidad", + "description": "Ayuda a mejorar Vibe-Kanban compartiendo datos de uso anónimos.", + "telemetry": { + "label": "Habilitar Telemetría", + "helper": "Habilita el seguimiento anónimo para ayudar a mejorar la aplicación. No se recopilan prompts ni información del proyecto." + } + }, + "taskTemplates": { + "title": "Plantillas de Tareas", + "description": "Gestiona las plantillas globales que se pueden usar en todos los proyectos." + }, + "safety": { + "title": "Avisos legales y de seguridad", + "description": "Reinicia las confirmaciones de seguridad y de introducción.", + "disclaimer": { + "title": "Confirmación de Descargo", + "description": "Restablecer el aviso de seguridad.", + "button": "Restablecer" + }, + "onboarding": { + "title": "Introducción", + "description": "Restablece el flujo de Introducción.", + "button": "Restablecer" + } + } + }, + "agents": { + "title": "Configuraciones de Agentes de Código", + "description": "Personaliza el comportamiento de los agentes con diferentes configuraciones.", + "loading": "Cargando configuraciones de agentes...", + "save": { + "button": "Guardar Configuraciones de Agentes", + "success": "✓ ¡Configuración guardada con éxito”!" + }, + "editor": { + "formLabel": "Editar JSON", + "agentLabel": "Agente", + "agentPlaceholder": "Seleccionar tipo", + "configLabel": "Configuración", + "configPlaceholder": "Seleccionar configuración", + "createNew": "Crear nuevo...", + "deleteTitle": "No se puede eliminar la última configuración", + "deleteButton": "Eliminar {{name}}", + "deleteText": "Eliminar", + "jsonLabel": "Configuración de Agente (JSON)", + "jsonPlaceholder": "Cargando perfiles...", + "jsonLoading": "Cargando...", + "pathLabel": "Ubicación del archivo de configuración:" + }, + "errors": { + "deleteFailed": "Error al eliminar la configuración. Por favor, inténtalo de nuevo.", + "saveFailed": "Error al guardar la configuración de los agentes. Por favor, inténtalo de nuevo.", + "saveConfigFailed": "Error al guardar la configuración. Por favor, inténtalo de nuevo." + } + }, + "mcp": { + "title": "Configuración de Servidor MCP", + "description": "Configura los servidores del Protocolo de Contexto de Modelos (MCP) para ampliar las capacidades del agente de codificación con herramientas y recursos personalizados.", + "loading": "Cargando configuración MCP...", + "applying": "Aplicando configuración...", + "labels": { + "agent": "Agente", + "agentPlaceholder": "Seleccionar", + "agentHelper": "Elige para qué agente configurar los servidores MCP.", + "serverConfig": "Configuración de Servidor (JSON)", + "popularServers": "Servidores populares", + "serverHelper": "Haz clic en una tarjeta para insertar ese Servidor MCP en el JSON de arriba.", + "saveLocation": "Los cambios se guardarán en:" + }, + "loading": { + "jsonEditor": "Cargando...", + "configuration": "Cargando configuración actual del servidor MCP..." + }, + "errors": { + "loadFailed": "Error al cargar la configuración.", + "invalidJson": "Formato JSON inválido", + "validationError": "Error de validación", + "saveFailed": "Error al guardar servidores MCP", + "applyFailed": "Error al aplicar la configuración del servidor MCP", + "addServerFailed": "Error al agregar servidor preconfigurado", + "mcpError": "Error de Configuración MCP: {{error}}", + "notSupported": "MCP No Soportado", + "supportMessage": "Para usar servidores MCP, por favor selecciona un agente diferente que soporte MCP (Claude, Amp, Gemini, Codex, o Opencode) arriba." + }, + "save": { + "button": "Guardar Configuración MCP", + "success": "¡Configuración Guardada!", + "successMessage": "✓ ¡Configuración MCP guardada exitosamente!", + "loading": "Cargando configuración actual del servidor MCP..." + } + } + } +} diff --git a/frontend/src/i18n/locales/ja/common.json b/frontend/src/i18n/locales/ja/common.json index 06418603..9a6b1580 100644 --- a/frontend/src/i18n/locales/ja/common.json +++ b/frontend/src/i18n/locales/ja/common.json @@ -20,6 +20,7 @@ "language": { "en": "English", "ja": "日本語", + "es": "Español", "browserDefault": "ブラウザ設定" }, "conversation": { diff --git a/frontend/src/pages/settings/GeneralSettings.tsx b/frontend/src/pages/settings/GeneralSettings.tsx index adf019b6..52d47f93 100644 --- a/frontend/src/pages/settings/GeneralSettings.tsx +++ b/frontend/src/pages/settings/GeneralSettings.tsx @@ -218,6 +218,9 @@ export function GeneralSettings() { {t('language.ja', { ns: 'common', defaultValue: '日本語' })} + + {t('language.es', { ns: 'common', defaultValue: 'Español' })} +

diff --git a/shared/types.ts b/shared/types.ts index b1768ecd..6b595546 100644 --- a/shared/types.ts +++ b/shared/types.ts @@ -100,7 +100,7 @@ export type GitHubConfig = { pat: string | null, oauth_token: string | null, use export enum SoundFile { ABSTRACT_SOUND1 = "ABSTRACT_SOUND1", ABSTRACT_SOUND2 = "ABSTRACT_SOUND2", ABSTRACT_SOUND3 = "ABSTRACT_SOUND3", ABSTRACT_SOUND4 = "ABSTRACT_SOUND4", COW_MOOING = "COW_MOOING", PHONE_VIBRATION = "PHONE_VIBRATION", ROOSTER = "ROOSTER" } -export type UiLanguage = "BROWSER" | "EN" | "JA"; +export type UiLanguage = "BROWSER" | "EN" | "JA" | "ES"; export type DeviceFlowStartResponse = { user_code: string, verification_uri: string, expires_in: number, interval: number, };