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:
+12
-11
@@ -9,6 +9,7 @@
|
||||
- AI Toolbox (to list, to table, frontmatter, to canvas)
|
||||
*/
|
||||
import { api } from './auth.js';
|
||||
import { t } from './i18n.js';
|
||||
|
||||
// ── API call helper ──
|
||||
async function aiAction(endpoint, text, extra = {}) {
|
||||
@@ -270,7 +271,7 @@ export async function createAIToolbar(container, getEditorView) {
|
||||
replaceSelection(v, result, 'append');
|
||||
showToast(t('ai.completion_added'), 'success');
|
||||
} catch (e) {
|
||||
showToast('AI: ' + (String(e.message || e).includes('401') ? 'clé API invalide' : e.message), 'error');
|
||||
showToast('AI: ' + (String(e.message || e).includes('401') ? t('ai.error_invalid_key') : e.message), 'error');
|
||||
} finally {
|
||||
aiBtn.innerHTML = origHTML;
|
||||
aiBtn.disabled = false;
|
||||
@@ -278,13 +279,13 @@ export async function createAIToolbar(container, getEditorView) {
|
||||
});
|
||||
|
||||
// ── Edit menu ──
|
||||
const editBtn = createDropdownBtn('Éditer', [
|
||||
{ label: '🪄 Improve writing', action: () => action('improve'), hint: 'Améliore la qualité du texte' },
|
||||
const editBtn = createDropdownBtn(t('ai.edit'), [
|
||||
{ label: '🪄 Improve writing', action: () => action('improve'), hint: t('ai.hint_improve') },
|
||||
{ label: '🔤 Fix spelling & grammar', action: () => action('fix-spelling'), hint: 'Corrige les fautes' },
|
||||
{ label: '📏 Make shorter', action: () => action('make-shorter'), hint: 'Rend le texte plus concis' },
|
||||
{ label: '📐 Make longer', action: () => action('make-longer'), hint: 'Ajoute des détails' },
|
||||
{ label: '📐 Make longer', action: () => action('make-longer'), hint: t('ai.hint_add_details') },
|
||||
{ label: '📋 Simplify language', action: () => action('simplify'), hint: 'Simplifie le langage' },
|
||||
], 'Modifie le texte sélectionné');
|
||||
], t('ai.hint_edit_selection'));
|
||||
|
||||
// ── Tone menu ──
|
||||
const toneBtn = createDropdownBtn('Ton', [
|
||||
@@ -300,14 +301,14 @@ export async function createAIToolbar(container, getEditorView) {
|
||||
{ label: '🇩🇪 German', action: () => action('translate', { target_lang: 'German' }) },
|
||||
{ label: '🇫🇷 French', action: () => action('translate', { target_lang: 'French' }) },
|
||||
{ label: '🇪🇸 Spanish', action: () => action('translate', { target_lang: 'Spanish' }) },
|
||||
], 'Traduit le texte sélectionné');
|
||||
], t('ai.hint_translate'));
|
||||
|
||||
// ── Generate menu ──
|
||||
const genBtn = createDropdownBtn('Générer', [
|
||||
const genBtn = createDropdownBtn(t('ai.generate'), [
|
||||
{ label: 'ℹ️ Explain this', action: () => action('explain', {}, 'append') },
|
||||
{ label: '📝 Summarize', action: () => action('summarize', {}, 'append') },
|
||||
{ label: '✏️ Continue writing', action: () => action('continue', {}, 'append') },
|
||||
], 'Génère du contenu à partir de la sélection');
|
||||
], t('ai.hint_generate'));
|
||||
|
||||
// ── Custom Rewrite ──
|
||||
const rewriteBtn = document.createElement('button');
|
||||
@@ -327,19 +328,19 @@ export async function createAIToolbar(container, getEditorView) {
|
||||
const v = ev();
|
||||
if (!v) return;
|
||||
const text = getSelection(v);
|
||||
const instruction = prompt('Instruction de réécriture :', '');
|
||||
const instruction = prompt(t('ai.rewrite_prompt'), '');
|
||||
if (!instruction) return;
|
||||
try {
|
||||
const result = await aiAction('rewrite', text, { instruction });
|
||||
replaceSelection(v, result);
|
||||
showToast(t('ai.text_rewritten'), 'success');
|
||||
} catch (e) {
|
||||
showToast('AI: ' + (String(e.message || e).includes('401') ? 'clé API invalide' : e.message), 'error');
|
||||
showToast('AI: ' + (String(e.message || e).includes('401') ? t('ai.error_invalid_key') : e.message), 'error');
|
||||
}
|
||||
});
|
||||
|
||||
// ── Toolbox menu ──
|
||||
const toolboxBtn = createDropdownBtn('🧰 Boîte', [
|
||||
const toolboxBtn = createDropdownBtn(t('ai.toolbox'), [
|
||||
{ label: '📋 Convert to list', action: () => action('to-list') },
|
||||
{ label: '📊 Convert to table', action: () => action('to-table') },
|
||||
{ label: '⚙️ Generate frontmatter', action: () => action('frontmatter', {}, 'before') },
|
||||
|
||||
Reference in New Issue
Block a user