fix: i18n for dashboard widgets + shortcuts — no more hardcoded French
Replaced all hardcoded French text in dashboard.js with t() calls:
- 'Chargement...' → t('common.loading')
- 'Erreur:' → t('dashboard.error_prefix')
- Size units ('o','Ko','Mo','Go') → t('dashboard.size_*')
- 'fichier(s)' → t('dashboard.count_files*')
- '0 fichiers' → t('dashboard.zero_files')
- 'Conflits de synchronisation' → t('dashboard.conflicts_title')
- 'Garder l\'original'/'Garder le conflit' → t('dashboard.keep_*')
- 'Ajouter/Retirer des bookmarks' → t('dashboard.bookmark_*')
- 'à l\'instant'/'il y a X min/h/j' → t('dashboard.*_ago', {n})
- 'Afficher'/'Masquer' → t('dashboard.show/hide')
- 'Erreur de chargement' → t('dashboard.load_error')
Added 11 shortcut i18n keys + 22 dashboard i18n keys to en.json/fr.json.
Verified: '4 files' count, English shortcuts, English empty states.
This commit is contained in:
+19
-19
@@ -21,18 +21,18 @@ const DashboardStatsWidget = {
|
||||
async load() {
|
||||
const grid = document.getElementById("dashboard-stats-grid");
|
||||
if (!grid) return;
|
||||
grid.innerHTML = '<div class="dashboard-stats-loading">Chargement...</div>';
|
||||
grid.innerHTML = `<div class="dashboard-stats-loading">${t('common.loading')}</div>`;
|
||||
try {
|
||||
const data = await api("/api/dashboard");
|
||||
this.render(data);
|
||||
} catch (err) {
|
||||
grid.innerHTML = `<div class="dashboard-recent-empty">Erreur: ${escapeHtml(err.message)}</div>`;
|
||||
grid.innerHTML = `<div class="dashboard-recent-empty">${t('dashboard.error_prefix')}${escapeHtml(err.message)}</div>`;
|
||||
}
|
||||
},
|
||||
render(data) {
|
||||
const grid = document.getElementById("dashboard-stats-grid");
|
||||
if (!grid) return;
|
||||
const fmtSize = (bytes) => bytes < 1024 ? `${bytes} o` : bytes < 1048576 ? `${(bytes/1024).toFixed(1)} Ko` : bytes < 1073741824 ? `${(bytes/1048576).toFixed(1)} Mo` : `${(bytes/1073741824).toFixed(1)} Go`;
|
||||
const fmtSize = (bytes) => bytes < 1024 ? `${bytes}${t('dashboard.size_bytes')}` : bytes < 1048576 ? `${(bytes/1024).toFixed(1)}${t('dashboard.size_kb')}` : bytes < 1073741824 ? `${(bytes/1048576).toFixed(1)}${t('dashboard.size_mb')}` : `${(bytes/1073741824).toFixed(1)}${t('dashboard.size_gb')}`;
|
||||
const items = [
|
||||
{ icon: "files", label: t('dashboard.stats_files'), value: data.total_files.toLocaleString() },
|
||||
{ icon: "tags", label: t('dashboard.stats_tags'), value: data.total_tags.toLocaleString() },
|
||||
@@ -120,7 +120,7 @@ const DashboardConflictsWidget = {
|
||||
<div class="dashboard-header">
|
||||
<div class="dashboard-title-row">
|
||||
<i data-lucide="alert-triangle" class="dashboard-icon" style="color:var(--accent-orange)"></i>
|
||||
<h2>Conflits de synchronisation</h2>
|
||||
<h2>${t('dashboard.conflicts_title')}</h2>
|
||||
<span class="dashboard-badge" style="background:var(--accent-orange)">${conflicts.length}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -130,11 +130,11 @@ const DashboardConflictsWidget = {
|
||||
<div class="conflict-info">
|
||||
<span class="conflict-vault">${escapeHtml(c.vault)}</span>
|
||||
<span class="conflict-name">${escapeHtml(c.conflict_path.split("/").pop())}</span>
|
||||
<span class="conflict-date">Conflit du ${c.conflict_date.replace(/(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})/, "$3/$2/$1 $4:$5")}</span>
|
||||
<span class="conflict-date">${t('dashboard.conflict_date')}${c.conflict_date.replace(/(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})/, "$3/$2/$1 $4:$5")}</span>
|
||||
</div>
|
||||
<div class="conflict-actions">
|
||||
<button class="conflict-btn keep-local" data-vault="${escapeHtml(c.vault)}" data-conflict="${escapeHtml(c.conflict_path)}" data-original="${escapeHtml(c.original_path)}">Garder l'original</button>
|
||||
<button class="conflict-btn keep-conflict" data-vault="${escapeHtml(c.vault)}" data-conflict="${escapeHtml(c.conflict_path)}" data-original="${escapeHtml(c.original_path)}">Garder le conflit</button>
|
||||
<button class="conflict-btn keep-local" data-vault="${escapeHtml(c.vault)}" data-conflict="${escapeHtml(c.conflict_path)}" data-original="${escapeHtml(c.original_path)}">${t('dashboard.keep_original')}</button>
|
||||
<button class="conflict-btn keep-conflict" data-vault="${escapeHtml(c.vault)}" data-conflict="${escapeHtml(c.conflict_path)}" data-original="${escapeHtml(c.original_path)}">${t('dashboard.keep_conflict')}</button>
|
||||
</div>
|
||||
</div>
|
||||
`).join("")}
|
||||
@@ -149,7 +149,7 @@ const DashboardConflictsWidget = {
|
||||
await api("/api/conflicts/resolve", { method: "POST", body: JSON.stringify({ vault: d.vault, conflict_path: d.conflict, original_path: d.original, action }) });
|
||||
showToast(t("dashboard.conflict_resolved"), "success");
|
||||
this.load();
|
||||
} catch (err) { showToast("Erreur: " + err.message, "error"); }
|
||||
} catch (err) { showToast(t('dashboard.error_prefix') + err.message, "error"); }
|
||||
}
|
||||
};
|
||||
|
||||
@@ -234,7 +234,7 @@ const DashboardRecentWidget = {
|
||||
}
|
||||
|
||||
if (empty) empty.classList.add("hidden");
|
||||
if (count) count.textContent = `${this._cache.length} fichier${this._cache.length > 1 ? "s" : ""}`;
|
||||
if (count) count.textContent = `${this._cache.length} ${this._cache.length > 1 ? t('dashboard.count_files_plural') : t('dashboard.count_files')}`;
|
||||
|
||||
if (!grid) return;
|
||||
grid.innerHTML = "";
|
||||
@@ -275,7 +275,7 @@ const DashboardRecentWidget = {
|
||||
|
||||
const bookmarkBtn = document.createElement("button");
|
||||
bookmarkBtn.className = `dashboard-card-bookmark-btn ${file.bookmarked ? "active" : ""}`;
|
||||
bookmarkBtn.title = file.bookmarked ? "Retirer des bookmarks" : "Ajouter aux bookmarks";
|
||||
bookmarkBtn.title = file.bookmarked ? t('dashboard.bookmark_remove') : t('dashboard.bookmark_add');
|
||||
bookmarkBtn.innerHTML = `<i data-lucide="${file.bookmarked ? "bookmark" : "bookmark-plus"}" style="width:14px;height:14px"></i>`;
|
||||
|
||||
bookmarkBtn.addEventListener("click", (e) => {
|
||||
@@ -347,7 +347,7 @@ const DashboardRecentWidget = {
|
||||
if (grid) grid.innerHTML = "";
|
||||
if (loading) loading.classList.remove("active");
|
||||
if (empty) empty.classList.remove("hidden");
|
||||
if (count) count.textContent = "0 fichiers";
|
||||
if (count) count.textContent = t('dashboard.zero_files');
|
||||
safeCreateIcons();
|
||||
},
|
||||
|
||||
@@ -356,17 +356,17 @@ const DashboardRecentWidget = {
|
||||
const empty = document.getElementById("dashboard-recent-empty");
|
||||
if (empty) {
|
||||
const msg = empty.querySelector("span");
|
||||
if (msg) msg.textContent = "Erreur de chargement";
|
||||
if (msg) msg.textContent = t('dashboard.load_error');
|
||||
}
|
||||
},
|
||||
|
||||
_humanizeDelta(mtime) {
|
||||
const delta = Date.now() / 1000 - mtime;
|
||||
if (delta < 60) return "à l'instant";
|
||||
if (delta < 3600) return `il y a ${Math.floor(delta / 60)} min`;
|
||||
if (delta < 86400) return `il y a ${Math.floor(delta / 3600)} h`;
|
||||
if (delta < 604800) return `il y a ${Math.floor(delta / 86400)} j`;
|
||||
return new Date(mtime * 1000).toLocaleDateString("fr-FR", { day: "numeric", month: "short", year: "numeric" });
|
||||
if (delta < 60) return t('dashboard.just_now');
|
||||
if (delta < 3600) return t('dashboard.min_ago', { n: Math.floor(delta / 60) });
|
||||
if (delta < 86400) return t('dashboard.hour_ago', { n: Math.floor(delta / 3600) });
|
||||
if (delta < 604800) return t('dashboard.day_ago', { n: Math.floor(delta / 86400) });
|
||||
return new Date(mtime * 1000).toLocaleDateString(getLocale() === 'fr' ? 'fr-FR' : 'en-US', { day: "numeric", month: "short", year: "numeric" });
|
||||
},
|
||||
|
||||
populateVaultFilter() {
|
||||
@@ -405,12 +405,12 @@ const DashboardRecentWidget = {
|
||||
if (localStorage.getItem('obsigate-qh-collapsed') === '1') {
|
||||
qhBody.classList.add('collapsed');
|
||||
qhToggle.textContent = '+';
|
||||
qhToggle.title = 'Afficher';
|
||||
qhToggle.title = t('dashboard.show');
|
||||
}
|
||||
qhToggle.addEventListener('click', function() {
|
||||
var collapsed = qhBody.classList.toggle('collapsed');
|
||||
qhToggle.textContent = collapsed ? '+' : '\u2212';
|
||||
qhToggle.title = collapsed ? 'Afficher' : 'Masquer';
|
||||
qhToggle.title = collapsed ? t('dashboard.show') : t('dashboard.hide');
|
||||
localStorage.setItem('obsigate-qh-collapsed', collapsed ? '1' : '0');
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user