feat: add 6 new locales (ja, ko, fr, es, de, pt) and UI polish
- Add Japanese, Korean, French, Spanish, German, Portuguese translations - Improve session active state visibility in both themes - Static language labels in LanguageSwitch component - Dark theme: lighten chat input background for better contrast - Fix system theme listener not toggling back to light Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,449 @@
|
||||
export default {
|
||||
// Login
|
||||
login: {
|
||||
title: 'Hermes Web UI',
|
||||
description: 'Entrez votre jeton d\'acces pour continuer. Retrouvez-le dans les journaux de demarrage du serveur.',
|
||||
placeholder: 'Jeton d\'acces',
|
||||
submit: 'Connexion',
|
||||
tokenRequired: 'Veuillez entrer votre jeton d\'acces',
|
||||
invalidToken: 'Jeton invalide',
|
||||
connectionFailed: 'Impossible de se connecter au serveur',
|
||||
},
|
||||
|
||||
// Common
|
||||
common: {
|
||||
loading: 'Chargement...',
|
||||
cancel: 'Annuler',
|
||||
delete: 'Supprimer',
|
||||
edit: 'Modifier',
|
||||
save: 'Enregistrer',
|
||||
saved: 'Enregistre',
|
||||
update: 'Mettre a jour',
|
||||
create: 'Creer',
|
||||
saveFailed: 'Echec de l\'enregistrement',
|
||||
ok: 'OK',
|
||||
copied: 'Copie',
|
||||
copy: 'Copier',
|
||||
noData: 'Aucune donnee',
|
||||
fetch: 'Recuperer',
|
||||
add: 'Ajouter',
|
||||
enable: 'Activer',
|
||||
disable: 'Desactiver',
|
||||
configured: 'Configure',
|
||||
notConfigured: 'Non configure',
|
||||
confirm: 'Confirmer',
|
||||
expand: 'Developper',
|
||||
collapse: 'Reduire',
|
||||
},
|
||||
|
||||
// Sidebar
|
||||
sidebar: {
|
||||
chat: 'Discussion',
|
||||
jobs: 'Taches planifiees',
|
||||
models: 'Modeles',
|
||||
profiles: 'Profils',
|
||||
skills: 'Competences',
|
||||
memory: 'Memoire',
|
||||
logs: 'Journaux',
|
||||
usage: 'Utilisation',
|
||||
channels: 'Canaux',
|
||||
terminal: 'Terminal',
|
||||
settings: 'Parametres',
|
||||
connected: 'Connecte',
|
||||
disconnected: 'Deconnecte',
|
||||
updateTip: 'Executez "hermes-web-ui update" dans le terminal pour mettre a jour',
|
||||
updateVersion: 'Mettre a jour vers v{version}',
|
||||
updating: 'Mise a jour...',
|
||||
updateSuccess: 'Mise a jour terminee, veuillez redemarrer le serveur',
|
||||
updateFailed: 'Echec de la mise a jour',
|
||||
},
|
||||
|
||||
// Chat
|
||||
chat: {
|
||||
emptyState: 'Demarrer une conversation avec Hermes Agent',
|
||||
inputPlaceholder: 'Tapez un message... (Entree pour envoyer, Shift+Entree pour un saut de ligne)',
|
||||
attachFiles: 'Joindre des fichiers',
|
||||
stop: 'Arreter',
|
||||
send: 'Envoyer',
|
||||
contextUsed: 'Contexte utilise :',
|
||||
sessions: 'Sessions',
|
||||
noSessions: 'Aucune session',
|
||||
newChat: 'Nouvelle discussion',
|
||||
deleteSession: 'Supprimer cette session ?',
|
||||
sessionDeleted: 'Session supprimee',
|
||||
rename: 'Renommer',
|
||||
copySessionId: 'Copier l\'ID de session',
|
||||
renamed: 'Renomme',
|
||||
renameFailed: 'Echec du renommage',
|
||||
renameSession: 'Renommer la session',
|
||||
enterNewTitle: 'Entrez un nouveau titre',
|
||||
other: 'Autre',
|
||||
runFailed: 'Echec de l\'execution',
|
||||
error: 'Erreur',
|
||||
tool: 'Outil',
|
||||
arguments: 'Arguments',
|
||||
result: 'Resultat',
|
||||
truncated: '... (tronque)',
|
||||
},
|
||||
|
||||
// Jobs
|
||||
jobs: {
|
||||
title: 'Taches planifiees',
|
||||
createJob: 'Creer une tache',
|
||||
editJob: 'Modifier la tache',
|
||||
noJobs: 'Aucune tache planifiee. Creez-en une pour commencer.',
|
||||
name: 'Nom',
|
||||
namePlaceholder: 'Nom de la tache',
|
||||
schedule: 'Planification (expression Cron)',
|
||||
schedulePlaceholder: 'ex. 0 9 * * *',
|
||||
quickPresets: 'Presets rapides',
|
||||
selectPreset: 'Selectionner un preset...',
|
||||
presetEveryMinute: 'Chaque minute',
|
||||
presetEvery5Min: 'Toutes les 5 minutes',
|
||||
presetEveryHour: 'Chaque heure',
|
||||
presetEveryDay: 'Tous les jours a 00:00',
|
||||
presetEveryDay9: 'Tous les jours a 09:00',
|
||||
presetEveryMonday: 'Chaque lundi a 09:00',
|
||||
presetEveryMonth: 'Le 1er de chaque mois a 09:00',
|
||||
prompt: 'Invite',
|
||||
promptPlaceholder: 'L\'invite a executer',
|
||||
deliverTarget: 'Cible de livraison',
|
||||
origin: 'Origine',
|
||||
local: 'Local',
|
||||
repeatCount: 'Nombre de repetitions (facultatif)',
|
||||
repeatPlaceholder: 'Laisser vide pour infini',
|
||||
jobCreated: 'Tache creee',
|
||||
jobUpdated: 'Tache mise a jour',
|
||||
nameRequired: 'Le nom est requis',
|
||||
scheduleRequired: 'La planification est requise',
|
||||
loadFailed: 'Echec du chargement de la tache',
|
||||
jobPaused: 'Tache en pause',
|
||||
jobResumed: 'Tache reprise',
|
||||
jobTriggered: 'Tache declenchee',
|
||||
jobDeleted: 'Tache supprimee',
|
||||
status: {
|
||||
running: 'En cours',
|
||||
paused: 'En pause',
|
||||
disabled: 'Desactivee',
|
||||
scheduled: 'Planifiee',
|
||||
},
|
||||
info: {
|
||||
schedule: 'Planification',
|
||||
lastRun: 'Derniere execution',
|
||||
nextRun: 'Prochaine execution',
|
||||
deliver: 'Livraison',
|
||||
repeat: 'Repetition',
|
||||
},
|
||||
action: {
|
||||
pause: 'Pause',
|
||||
pauseJob: 'Mettre en pause',
|
||||
resume: 'Reprendre',
|
||||
resumeJob: 'Reprendre la tache',
|
||||
runNow: 'Executer maintenant',
|
||||
triggerImmediately: 'Declencher immediatement',
|
||||
},
|
||||
},
|
||||
|
||||
// Skills
|
||||
skills: {
|
||||
title: 'Competences',
|
||||
searchPlaceholder: 'Rechercher des competences...',
|
||||
noMatch: 'Aucune competence ne correspond a votre recherche',
|
||||
noSkills: 'Aucune competence trouvee',
|
||||
backTo: 'Retour a',
|
||||
attachedFiles: 'Fichiers joints',
|
||||
loadFailed: 'Echec du chargement de la competence',
|
||||
fileLoadFailed: 'Echec du chargement du fichier',
|
||||
toggleFailed: 'Echec de l\'activation/desactivation de la competence',
|
||||
},
|
||||
|
||||
// Memory
|
||||
memory: {
|
||||
title: 'Memoire',
|
||||
refresh: 'Actualiser',
|
||||
loadFailed: 'Echec du chargement de la memoire',
|
||||
myNotes: 'Mes notes',
|
||||
noNotes: 'Aucune note pour l\'instant.',
|
||||
notesPlaceholder: 'Ecrivez vos notes...',
|
||||
userProfile: 'Profil utilisateur',
|
||||
noProfile: 'Aucun profil pour l\'instant.',
|
||||
profilePlaceholder: 'Ecrivez votre profil...',
|
||||
soul: 'Ame',
|
||||
noSoul: 'Aucune configuration d\'ame pour l\'instant.',
|
||||
soulPlaceholder: 'Ecrivez la configuration de l\'ame...',
|
||||
},
|
||||
|
||||
// Models
|
||||
models: {
|
||||
title: 'Modeles',
|
||||
addProvider: 'Ajouter un fournisseur',
|
||||
providerType: 'Type de fournisseur',
|
||||
preset: 'Preset',
|
||||
custom: 'Personnalise',
|
||||
selectProvider: 'Selectionner un fournisseur',
|
||||
chooseProvider: 'Choisir un fournisseur...',
|
||||
name: 'Nom',
|
||||
autoGeneratedName: 'Genere automatiquement a partir de l\'URL de base',
|
||||
baseUrl: 'URL de base',
|
||||
baseUrlPlaceholder: 'ex. https://api.example.com/v1',
|
||||
apiKey: 'Cle API',
|
||||
apiKeyPlaceholder: 'sk-...',
|
||||
defaultModel: 'Modele par defaut',
|
||||
selectModel: 'Selectionner un modele...',
|
||||
providerAdded: 'Fournisseur ajoute',
|
||||
providerDeleted: 'Fournisseur supprime',
|
||||
deleteProvider: 'Supprimer le fournisseur',
|
||||
deleteConfirm: 'Etes-vous sur de vouloir supprimer "{name}" ?',
|
||||
noProviders: 'Aucun fournisseur trouve. Ajoutez un fournisseur personnalise pour commencer.',
|
||||
builtIn: 'Integre',
|
||||
customType: 'Personnalise',
|
||||
provider: 'Fournisseur',
|
||||
local: 'Local ({host})',
|
||||
selectProviderRequired: 'Veuillez selectionner un fournisseur',
|
||||
baseUrlRequired: 'L\'URL de base est requise',
|
||||
apiKeyRequired: 'La cle API est requise',
|
||||
modelRequired: 'Le modele par defaut est requis',
|
||||
enterBaseUrl: 'Veuillez d\'abord entrer l\'URL de base',
|
||||
unexpectedFormat: 'Format de reponse inattendu',
|
||||
foundModels: '{count} modeles trouves',
|
||||
fetchFailed: 'Echec de la recuperation des modeles',
|
||||
},
|
||||
|
||||
// Profiles
|
||||
profiles: {
|
||||
title: 'Profils',
|
||||
create: 'Creer un profil',
|
||||
import: 'Importer',
|
||||
export: 'Exporter',
|
||||
rename: 'Renommer',
|
||||
delete: 'Supprimer',
|
||||
switchTo: 'Passer a',
|
||||
switchConfirm: 'Le passage au profil "{name}" redemarrera la passerelle. Continuer ?',
|
||||
switchSuccess: 'Profil "{name}" actif',
|
||||
switchFailed: 'Echec du changement de profil. La passerelle peut necessiter un redemarrage manuel.',
|
||||
createSuccess: 'Profil "{name}" cree',
|
||||
createFailed: 'Echec de la creation du profil',
|
||||
renameSuccess: 'Profil renomme',
|
||||
renameFailed: 'Echec du renommage du profil',
|
||||
deleteConfirm: 'Etes-vous sur de vouloir supprimer le profil "{name}" ?',
|
||||
deleteSuccess: 'Profil supprime',
|
||||
deleteFailed: 'Echec de la suppression du profil',
|
||||
exportSuccess: 'Profil exporte',
|
||||
exportFailed: 'Echec de l\'exportation du profil',
|
||||
importSuccess: 'Profil importe',
|
||||
importFailed: 'Echec de l\'importation du profil',
|
||||
importSelectFile: 'Selectionner un fichier d\'archive',
|
||||
importInvalidFile: 'Veuillez selectionner une archive valide (.tar.gz, .tgz, .gz, .zip)',
|
||||
name: 'Nom du profil',
|
||||
namePlaceholder: 'Lettres, chiffres et tirets uniquement',
|
||||
newName: 'Nouveau nom',
|
||||
newNamePlaceholder: 'Entrez un nouveau nom',
|
||||
cloneFromCurrent: 'Cloner depuis le profil actuel',
|
||||
archivePath: 'Chemin de l\'archive',
|
||||
archivePathPlaceholder: 'Chemin serveur du fichier d\'archive',
|
||||
importName: 'Nom du profil (facultatif)',
|
||||
importNamePlaceholder: 'Laisser vide pour utiliser le nom de l\'archive',
|
||||
active: 'Actif',
|
||||
model: 'Modele',
|
||||
gateway: 'Passerelle',
|
||||
alias: 'Alias',
|
||||
provider: 'Fournisseur',
|
||||
path: 'Chemin',
|
||||
skills: 'Competences',
|
||||
hasEnv: 'A un .env',
|
||||
hasSoulMd: 'A un soul.md',
|
||||
noProfiles: 'Aucun profil trouve. Creez-en un pour commencer.',
|
||||
},
|
||||
|
||||
// Logs
|
||||
logs: {
|
||||
title: 'Journaux',
|
||||
all: 'Tout',
|
||||
searchPlaceholder: 'Rechercher...',
|
||||
refresh: 'Actualiser',
|
||||
noEntries: 'Aucune entree de journal',
|
||||
},
|
||||
|
||||
// Settings
|
||||
settings: {
|
||||
title: 'Parametres',
|
||||
saved: 'Enregistre',
|
||||
saveFailed: 'Echec de l\'enregistrement',
|
||||
tabs: {
|
||||
display: 'Affichage',
|
||||
agent: 'Agent',
|
||||
memory: 'Memoire',
|
||||
session: 'Session',
|
||||
privacy: 'Confidentialite',
|
||||
apiServer: 'Serveur API',
|
||||
},
|
||||
display: {
|
||||
streaming: 'Reponses en continu',
|
||||
streamingHint: 'Afficher les reponses de l\'IA en temps reel',
|
||||
compact: 'Mode compact',
|
||||
compactHint: 'Reduire l\'espacement des messages',
|
||||
showReasoning: 'Afficher le raisonnement',
|
||||
showReasoningHint: 'Afficher le processus de reflexion du modele',
|
||||
showCost: 'Afficher le cout',
|
||||
showCostHint: 'Afficher l\'utilisation des jetons dans les reponses',
|
||||
inlineDiffs: 'Diffs en ligne',
|
||||
inlineDiffsHint: 'Afficher les changements de code en ligne',
|
||||
bellOnComplete: 'Son de fin',
|
||||
bellOnCompleteHint: 'Jouer un son lorsque l\'IA a termine',
|
||||
busyInputMode: 'Mode saisie active',
|
||||
busyInputModeHint: 'Permettre la saisie pendant le traitement de l\'IA',
|
||||
theme: 'Theme',
|
||||
themeHint: 'Choisir clair, sombre ou suivre les preferences du systeme',
|
||||
themeLight: 'Clair',
|
||||
themeDark: 'Sombre',
|
||||
themeSystem: 'Systeme',
|
||||
},
|
||||
agent: {
|
||||
maxTurns: 'Tours maximum',
|
||||
maxTurnsHint: 'Nombre maximum de tours d\'interaction par conversation',
|
||||
gatewayTimeout: 'Delai d\'attente de la passerelle',
|
||||
gatewayTimeoutHint: 'Delai d\'attente de la requete en secondes',
|
||||
restartDrainTimeout: 'Delai de vidange au redemarrage',
|
||||
restartDrainTimeoutHint: 'Delai de vidange avant redemarrage en secondes',
|
||||
toolEnforcement: 'Application des outils',
|
||||
toolEnforcementHint: 'Controler le mode d\'execution des appels d\'outils',
|
||||
auto: 'Automatique',
|
||||
always: 'Toujours',
|
||||
never: 'Jamais',
|
||||
},
|
||||
memory: {
|
||||
enabled: 'Activer la memoire',
|
||||
enabledHint: 'Permettre a l\'IA de memoriser le contexte de conversation',
|
||||
userProfile: 'Profil utilisateur',
|
||||
userProfileHint: 'Permettre a l\'IA de memoriser les preferences utilisateur',
|
||||
charLimit: 'Limite de caracteres de la memoire',
|
||||
charLimitHint: 'Nombre maximum de caracteres pour MEMORY.md',
|
||||
userCharLimit: 'Limite de caracteres du profil utilisateur',
|
||||
userCharLimitHint: 'Nombre maximum de caracteres pour USER.md',
|
||||
},
|
||||
session: {
|
||||
mode: 'Mode de reinitialisation',
|
||||
modeHint: 'Condition de declenchement de la reinitialisation de session',
|
||||
modeBoth: 'Inactivite + Planifie',
|
||||
modeIdle: 'Inactivite uniquement',
|
||||
modeHourly: 'Planifie uniquement',
|
||||
idleMinutes: 'Delai d\'inactivite',
|
||||
idleMinutesHint: 'Temps d\'attente avant reinitialisation automatique (minutes)',
|
||||
atHour: 'Heure de reinitialisation planifiee',
|
||||
atHourHint: 'Reinitialiser la session a cette heure chaque jour',
|
||||
},
|
||||
privacy: {
|
||||
redactPii: 'Masquer les DPI',
|
||||
redactPiiHint: 'Detecter et masquer automatiquement les informations sensibles (mots de passe, cles, etc.)',
|
||||
},
|
||||
apiServer: {
|
||||
enable: 'Activer',
|
||||
enableHint: 'Activer le serveur API',
|
||||
host: 'Hote',
|
||||
hostHint: 'Adresse d\'ecoute',
|
||||
port: 'Port',
|
||||
portHint: 'Port d\'ecoute',
|
||||
key: 'Cle',
|
||||
keyHint: 'Cle d\'acces API',
|
||||
cors: 'Origines CORS',
|
||||
corsHint: 'Sources cross-origin autorisees',
|
||||
},
|
||||
},
|
||||
|
||||
// Platform channel settings
|
||||
platform: {
|
||||
requireMention: "Exiger une mention {'@'}",
|
||||
requireMentionGroup: "Exiger une mention {'@'} dans les groupes pour repondre",
|
||||
requireMentionChannel: "Exiger une mention {'@'} dans les canaux pour repondre",
|
||||
requireMentionRoom: "Exiger une mention {'@'} dans les salles pour repondre",
|
||||
reactions: 'Reactions',
|
||||
reactionsHint: 'Reagir aux messages avec des emoji',
|
||||
freeResponseChats: 'Discussions en reponse libre',
|
||||
freeResponseChatsHint: "ID de discussions repondant sans mention {'@'} (separes par des virgules)",
|
||||
freeResponseChannels: 'Canaux en reponse libre',
|
||||
freeResponseChannelsHint: "ID de canaux repondant sans mention {'@'} (separes par des virgules)",
|
||||
freeResponseRooms: 'Salles en reponse libre',
|
||||
freeResponseRoomsHint: "ID de salles repondant sans mention {'@'} (separes par des virgules)",
|
||||
mentionPatterns: 'Motifs de mention personnalises',
|
||||
mentionPatternsHint: 'Motifs de declenchement supplementaires',
|
||||
autoThread: 'Fil automatique',
|
||||
autoThreadHint: "Creer automatiquement des fils de reponse apres une mention {'@'}",
|
||||
autoThreadHintRoom: 'Creer automatiquement des fils de reponse dans les salles',
|
||||
dmMentionThreads: 'Fils de mention en MP',
|
||||
dmMentionThreadsHint: 'Utiliser des fils de reponse pour les mentions en MP',
|
||||
allowBots: 'Autoriser les messages de bots',
|
||||
allowBotsHint: 'Repondre aux messages d\'autres bots',
|
||||
allowedChannels: 'Canaux autorises',
|
||||
allowedChannelsHint: 'Liste blanche des ID de canaux (separes par des virgules)',
|
||||
ignoredChannels: 'Canaux ignores',
|
||||
ignoredChannelsHint: 'Canaux ou le bot ne repond jamais (separes par des virgules)',
|
||||
noThreadChannels: 'Canaux sans fil',
|
||||
noThreadChannelsHint: 'Canaux ou le bot repond sans fil (separes par des virgules)',
|
||||
botToken: 'Jeton de bot',
|
||||
botTokenHint: 'Jeton de bot depuis le portail developpeur',
|
||||
accessToken: 'Jeton d\'acces',
|
||||
accessTokenHint: 'Jeton d\'acces Matrix',
|
||||
homeserver: 'URL du serveur domestique',
|
||||
homeserverHint: 'URL du serveur domestique Matrix',
|
||||
appId: 'ID de l\'application',
|
||||
appIdHint: 'ID de l\'application Feishu',
|
||||
appSecret: 'Secret de l\'application',
|
||||
appSecretHint: 'Secret de l\'application Feishu',
|
||||
clientId: 'ID client',
|
||||
clientIdHint: 'ID client DingTalk',
|
||||
clientSecret: 'Secret client',
|
||||
clientSecretHint: 'Secret client DingTalk',
|
||||
botId: 'ID du bot',
|
||||
botIdHint: 'ID du bot WeCom',
|
||||
wecomSecretHint: 'Secret du bot WeCom',
|
||||
waEnabled: 'Activer WhatsApp',
|
||||
waEnabledHint: 'Activer WhatsApp via appairage par code QR',
|
||||
weixinToken: 'Jeton Weixin',
|
||||
weixinTokenHint: 'Depuis la connexion QR de la CLI weixin (hermes weixin)',
|
||||
accountId: 'ID de compte',
|
||||
accountIdHint: 'ID du compte Weixin',
|
||||
qrLogin: 'Connexion QR',
|
||||
qrRelogin: 'Reconnexion',
|
||||
qrFetching: 'Recuperation du code QR...',
|
||||
qrScanHint: 'Scannez avec WeChat pour vous connecter',
|
||||
qrScanedHint: 'Scanne, veuillez confirmer sur le telephone...',
|
||||
},
|
||||
|
||||
// Language
|
||||
language: {
|
||||
label: 'Langue',
|
||||
zh: '中文',
|
||||
en: 'English',
|
||||
fr: 'Francais',
|
||||
},
|
||||
|
||||
// Terminal
|
||||
terminal: {
|
||||
sessions: 'Sessions',
|
||||
newTab: 'Nouveau terminal',
|
||||
closeSession: 'Fermer cette session ?',
|
||||
sessionExited: 'Terminee',
|
||||
processExited: 'Processus termine avec le code {code}',
|
||||
},
|
||||
|
||||
// Usage
|
||||
usage: {
|
||||
title: 'Statistiques d\'utilisation',
|
||||
refresh: 'Actualiser',
|
||||
totalTokens: 'Total des jetons',
|
||||
inputTokens: 'Entree',
|
||||
outputTokens: 'Sortie',
|
||||
totalSessions: 'Total des sessions',
|
||||
avgPerDay: '~{n}/jour en moy.',
|
||||
estimatedCost: 'Cout est.',
|
||||
cacheHitRate: 'Taux de succes du cache',
|
||||
modelBreakdown: 'Repartition par modele',
|
||||
dailyTrend: 'Utilisation quotidienne (30 derniers jours)',
|
||||
date: 'Date',
|
||||
tokens: 'Jetons',
|
||||
cache: 'Cache',
|
||||
sessions: 'Sessions',
|
||||
cost: 'Cout',
|
||||
noData: 'Aucune donnee d\'utilisation',
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user