i18n: complete remaining roadmap tasks
JS files: - ai.js: add t() import, replace 10 hardcoded French strings - sync.js: add t() import, replace 20 hardcoded French strings (toasts, status labels, events, AI panel) - graph.js: add t() import, replace 6 hardcoded French strings (tooltips, badges) Locales: - +36 new keys for ai.js, sync.js, graph.js - 1206 keys in each locale file (perfectly synchronized) - 0 French characters remaining in en.json Documentation: - README.fr.md created (French version) - ROADMAP.md point #63 updated to 100% complete
This commit is contained in:
+22
-21
@@ -1,5 +1,6 @@
|
||||
/* ObsiGate — Sync: SSE client + PWA registration + Offline mode */
|
||||
import { state } from './state.js';
|
||||
import { t } from './i18n.js';
|
||||
import { showToast } from './ui.js';
|
||||
import { api } from './auth.js';
|
||||
import { loadVaults, loadTags, refreshTagsForContext, refreshSidebarTreePreservingState } from './sidebar.js';
|
||||
@@ -59,7 +60,7 @@ export const IndexUpdateManager = (() => {
|
||||
try {
|
||||
const data = JSON.parse(e.data);
|
||||
_addEvent("vault_added", data);
|
||||
showToast(`Vault "${data.vault}" ajouté (${data.stats.file_count} fichiers)`, "info");
|
||||
showToast(t('sync.vault_added', { vault: data.vault, count: data.stats.file_count }), "info");
|
||||
loadVaults();
|
||||
loadTags();
|
||||
} catch (err) {
|
||||
@@ -71,7 +72,7 @@ export const IndexUpdateManager = (() => {
|
||||
try {
|
||||
const data = JSON.parse(e.data);
|
||||
_addEvent("vault_removed", data);
|
||||
showToast(`Vault "${data.vault}" supprimé`, "info");
|
||||
showToast(t('sync.vault_removed', { vault: data.vault }), "info");
|
||||
loadVaults();
|
||||
loadTags();
|
||||
} catch (err) {
|
||||
@@ -85,7 +86,7 @@ export const IndexUpdateManager = (() => {
|
||||
_addEvent("index_start", data);
|
||||
connectionState = "syncing";
|
||||
_updateBadge();
|
||||
showToast(`Indexation démarrée (${data.total_vaults} vaults)`, "info");
|
||||
showToast(t('sync.index_started', { count: data.total_vaults }), "info");
|
||||
} catch (err) {
|
||||
console.error("SSE parse error:", err);
|
||||
}
|
||||
@@ -110,7 +111,7 @@ export const IndexUpdateManager = (() => {
|
||||
_addEvent("index_complete", data);
|
||||
connectionState = "connected";
|
||||
_updateBadge();
|
||||
showToast(`Indexation terminée (${data.total_files} fichiers)`, "success");
|
||||
showToast(t('sync.index_complete', { count: data.total_files }), "success");
|
||||
loadVaults();
|
||||
loadTags();
|
||||
} catch (err) {
|
||||
@@ -204,10 +205,10 @@ export const IndexUpdateManager = (() => {
|
||||
if (!badge) return;
|
||||
badge.className = "sync-badge sync-badge--" + connectionState;
|
||||
const labels = {
|
||||
disconnected: "Déconnecté",
|
||||
disconnected: t('sync.disconnected'),
|
||||
connecting: "Connexion...",
|
||||
connected: "Synchronisé",
|
||||
syncing: "Mise à jour...",
|
||||
connected: t('sync.connected'),
|
||||
syncing: t('sync.updating'),
|
||||
};
|
||||
badge.title = labels[connectionState] || connectionState;
|
||||
}
|
||||
@@ -289,9 +290,9 @@ function _renderSyncPanel(panel) {
|
||||
const events = IndexUpdateManager.getRecentEvents();
|
||||
|
||||
const stateLabels = {
|
||||
disconnected: "Déconnecté",
|
||||
disconnected: t('sync.disconnected'),
|
||||
connecting: "Connexion...",
|
||||
connected: "Connecté",
|
||||
connected: t('sync.connected_short'),
|
||||
syncing: "Synchronisation...",
|
||||
};
|
||||
|
||||
@@ -301,18 +302,18 @@ function _renderSyncPanel(panel) {
|
||||
</div>`;
|
||||
|
||||
if (events.length === 0) {
|
||||
html += `<div class="sync-panel__empty">Aucun événement récent</div>`;
|
||||
html += `<div class="sync-panel__empty">${t('sync.no_recent_events')}</div>`;
|
||||
} else {
|
||||
html += `<div class="sync-panel__events">`;
|
||||
events.slice(0, 10).forEach((ev) => {
|
||||
const time = new Date(ev.timestamp).toLocaleTimeString();
|
||||
const typeLabels = {
|
||||
index_updated: "Mise à jour",
|
||||
index_updated: t('sync.event_index_updated'),
|
||||
index_reloaded: "Rechargement",
|
||||
vault_added: "Vault ajouté",
|
||||
vault_removed: "Vault supprimé",
|
||||
index_start: "Démarrage index.",
|
||||
index_progress: "Vault indexé",
|
||||
vault_added: t('sync.event_vault_added'),
|
||||
vault_removed: t('sync.event_vault_removed'),
|
||||
index_start: t('sync.event_index_start'),
|
||||
index_progress: t('sync.event_index_progress'),
|
||||
index_complete: "Indexation tech.",
|
||||
};
|
||||
const label = typeLabels[ev.type] || ev.type;
|
||||
@@ -378,7 +379,7 @@ function _renderAIStatusSection(panel) {
|
||||
extClass = 'sync-panel__ai--inactive';
|
||||
} else {
|
||||
extIcon = 'help-circle';
|
||||
extText = 'Vérification…';
|
||||
extText = t('sync.verifying');
|
||||
extClass = 'sync-panel__ai--unknown';
|
||||
}
|
||||
|
||||
@@ -386,11 +387,11 @@ function _renderAIStatusSection(panel) {
|
||||
let acIcon, acText, acClass;
|
||||
if (_aiAutocomplete && _aiAutocomplete.available) {
|
||||
acIcon = 'check-circle';
|
||||
acText = 'Auto-complétion active';
|
||||
acText = t('sync.autocomplete_active');
|
||||
acClass = 'sync-panel__ai--active';
|
||||
} else if (_aiAutocomplete && _aiAutocomplete.server_ok && !_aiAutocomplete.model_loaded) {
|
||||
acIcon = 'alert-triangle';
|
||||
acText = 'Modèle non chargé';
|
||||
acText = t('sync.model_not_loaded');
|
||||
acClass = 'sync-panel__ai--inactive';
|
||||
} else if (_aiAutocomplete && _aiAutocomplete.error) {
|
||||
acIcon = 'x-circle';
|
||||
@@ -398,11 +399,11 @@ function _renderAIStatusSection(panel) {
|
||||
acClass = 'sync-panel__ai--inactive';
|
||||
} else if (_aiAutocomplete === null) {
|
||||
acIcon = 'help-circle';
|
||||
acText = 'Vérification…';
|
||||
acText = t('sync.verifying');
|
||||
acClass = 'sync-panel__ai--unknown';
|
||||
} else {
|
||||
acIcon = 'x-circle';
|
||||
acText = 'Non configuré';
|
||||
acText = t('sync.not_configured');
|
||||
acClass = 'sync-panel__ai--inactive';
|
||||
}
|
||||
|
||||
@@ -416,7 +417,7 @@ function _renderAIStatusSection(panel) {
|
||||
'</span>' +
|
||||
'</div>' +
|
||||
'<div class="sync-panel__ai-row">' +
|
||||
'<span class="sync-panel__ai-label">Auto-complétion</span>' +
|
||||
'<span class="sync-panel__ai-label">' + t('sync.autocomplete') + '</span>' +
|
||||
'<span class="sync-panel__ai-state ' + acClass + '" data-lucide-icon="' + acIcon + '">' +
|
||||
'<i data-lucide="' + acIcon + '" style="width:14px;height:14px"></i>' +
|
||||
acText +
|
||||
|
||||
Reference in New Issue
Block a user