Files
vibe-kanban/frontend/src/i18n/locales/es/settings.json

181 lines
7.6 KiB
JSON
Raw Normal View History

{
"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)",
"backToApp": "Volver a la app"
}
},
"general": {
"loading": "Cargando configuración...",
"loadError": "Error al cargar la configuración.",
"save": {
"button": "Guardar Configuración",
"success": "✓ ¡Configuración guardada!",
Don't update settings as soon as they're changed (vibe-kanban) (#839) * ## Task Complete! ✅ I have successfully implemented the solution to fix the premature config updates issue in GeneralSettings.tsx. Here's what has been accomplished: ### **Changes Made:** 1. **Added Utility Functions** - `deepClone()` - Safely clones objects for draft state - `deepMerge()` - Merges partial updates into draft config - `isEqual()` - Compares objects to detect unsaved changes 2. **Implemented Draft State Management** - Added `draft` state that mirrors the current config - Added `dirty` flag to track form modifications - Added `updateDraft()` helper to update draft without affecting global config - Added `hasUnsavedChanges` computed property for UI state 3. **Updated All Form Fields** - **Theme selector** - now updates draft only - **Language selector** - now updates draft only - **Executor profile** - now updates draft only - **Editor type** - now updates draft only - **GitHub PAT** - now updates draft only - **Sound notifications** - now updates draft only (with preview using draft) - **Push notifications** - now updates draft only - **Analytics** - now updates draft only 4. **Enhanced Save/Discard Functionality** - `handleSave()` now applies draft to global config via `updateAndSaveConfig()` - `handleDiscard()` resets draft back to current config - Both buttons are properly enabled/disabled based on unsaved changes 5. **Improved User Experience** - Added "You have unsaved changes" indicator in sticky footer - Save button only enabled when there are changes to save - Discard button only enabled when there are changes to discard - Optional browser warning on page navigation with unsaved changes - All immediate actions (OAuth, safety resets) still work instantly via `updateAndSaveConfig` ### **Benefits:** - ✅ **No more confusing auto-apply behavior** - changes only apply when Save is clicked - ✅ **Clear visual feedback** - users see when they have unsaved changes - ✅ **Ability to discard changes** - users can revert unwanted modifications - ✅ **Consistent UX** - matches standard form behavior expectations - ✅ **Backwards compatible** - all existing functionality preserved ### **Testing Results:** - ✅ TypeScript compilation passes - ✅ ESLint validation passes - ✅ Full build completes successfully - ✅ No new lint warnings introduced The implementation successfully resolves the original issue where users thought settings were auto-saved when they were only being applied temporarily. Now the UI clearly differentiates between "staging" changes (draft) and "applying" changes (save), giving users full control over when their configuration changes take effect. * Cleanup script changes for task attempt bcb52aeb-7bd2-44b3-ac05-e99327631c35 * Excellent! The number of lint warnings actually went down from 105 to 98, which means our refactoring improved the code quality. This is because lodash's `isEqual` provides better type inference than our custom JSON.stringify comparison. ## Summary Perfect! I have successfully replaced the custom utility functions with lodash implementations. Here's what was improved: ### **Changes Made:** 1. **Added Lodash Dependencies** - Added `lodash` as a dependency - Added `@types/lodash` as a dev dependency for TypeScript support 2. **Replaced Custom Utility Functions** - `deepClone()` → `cloneDeep()` from lodash - `deepMerge()` → `merge()` from lodash - `isEqual()` → `isEqual()` from lodash 3. **Updated All References** - Updated draft state initialization - Updated draft sync when config changes - Updated the `updateDraft()` helper function - Updated the `handleDiscard()` function ### **Benefits of Using Lodash:** ✅ **Better Performance** - Lodash functions are highly optimized and battle-tested ✅ **Improved Type Safety** - Better TypeScript integration and type inference ✅ **More Robust** - Handles edge cases that custom implementations might miss ✅ **Reduced Code** - Eliminated ~30 lines of custom utility code ✅ **Better Lint Warnings** - Reduced from 105 to 98 ESLint warnings ✅ **Industry Standard** - Using well-known, widely-adopted utility functions ### **Testing Results:** - ✅ TypeScript compilation passes - ✅ ESLint validation passes with fewer warnings - ✅ Frontend build completes successfully - ✅ All functionality preserved The implementation now uses professional-grade utility functions while maintaining all the draft state management functionality we implemented for the deferred save feature. This makes the code more maintainable and reliable. * Perfect! The i18n lint check passed specifically for our GeneralSettings.tsx file - no issues were reported for it, which means all our strings are now properly internationalized. ## Summary ✅ I successfully identified and fixed **3 hardcoded i18n strings** in the GeneralSettings.tsx file: ### **Found Issues:** 1. **Line 725**: `"• You have unsaved changes"` (hardcoded English) 2. **Line 736**: `"Discard"` (hardcoded English) 3. **Line 136**: `"Failed to save configuration"` (hardcoded English) ### **Fixed by:** 1. **Added translation keys** to all 3 locales: - **English** (`en/settings.json`): - `"unsavedChanges": "• You have unsaved changes"` - `"discard": "Discard"` - **Spanish** (`es/settings.json`): - `"unsavedChanges": "• Tienes cambios sin guardar"` - `"discard": "Descartar"` - **Japanese** (`ja/settings.json`): - `"unsavedChanges": "• 未保存の変更があります"` - `"discard": "破棄"` 2. **Updated React component** to use translation functions: - `"• You have unsaved changes"` → `{t('settings.general.save.unsavedChanges')}` - `"Discard"` → `{t('settings.general.save.discard')}` - `"Failed to save configuration"` → `{t('settings.general.save.error')}` ### **Results:** - ✅ **All hardcoded strings replaced** with proper i18n calls - ✅ **Translations added** for English, Spanish, and Japanese - ✅ **TypeScript compilation passes** - ✅ **i18n lint check passes** (no warnings for GeneralSettings.tsx) - ✅ **User experience** now supports multiple languages The GeneralSettings component is now fully internationalized and will properly display the unsaved changes indicator and discard button text in the user's selected language.
2025-09-24 18:06:50 +01:00
"error": "Error al guardar la configuración",
"unsavedChanges": "• Tienes cambios sin guardar",
"discard": "Descartar"
},
"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",
"defaultLabel": "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.",
"or": "O",
"pat": {
"label": "Token de Acceso Personal",
"helper": "Token de Acceso Personal de GitHub con permisos 'repo'. Úsalo si los permisos OAuth son insuficientes para repositorios privados y repositorios de organizaciones.",
"createTokenLink": "Crear token aquí"
}
},
"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": {
"jsonEditor": "Cargando...",
"configuration": "Cargando configuración actual del servidor 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:"
},
"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..."
}
}
}
}