chore: even more i18n and no end in sight

This commit is contained in:
2026-02-21 13:24:03 +01:00
parent 0082291fa4
commit e5088d06e8
8 changed files with 262 additions and 43 deletions

View File

@@ -1245,6 +1245,7 @@ const TaxonomySection: React.FC<{
onMappingsAnalyzed: (categoryMappings: Record<string, string>, tagMappings: Record<string, string>) => void;
onMappingUpdated: (type: 'category' | 'tag', itemName: string, mappedTo: string | undefined) => void;
}> = ({ categories, tags, expanded, onToggle, onMappingsAnalyzed, onMappingUpdated }) => {
const { t } = useI18n();
const [isAnalyzing, setIsAnalyzing] = useState(false);
const [showModelSelector, setShowModelSelector] = useState(false);
const [availableModels, setAvailableModels] = useState<ChatModel[]>([]);
@@ -1335,10 +1336,10 @@ const TaxonomySection: React.FC<{
<div className="import-detail-section">
<h3 onClick={onToggle}>
<span className={`toggle-icon ${expanded ? 'open' : ''}`}>&#9654;</span>
Categories & Tags
{t('importAnalysis.taxonomyTitle')}
{(mappedCategoriesCount > 0 || mappedTagsCount > 0) && (
<span className="taxonomy-mapped-count">
{mappedCategoriesCount + mappedTagsCount} mapped
{t('importAnalysis.mappedCount', { count: mappedCategoriesCount + mappedTagsCount })}
</span>
)}
</h3>
@@ -1354,14 +1355,14 @@ const TaxonomySection: React.FC<{
{isAnalyzing ? (
<>
<span className="import-spinner small" />
Analyzing...
{t('importAnalysis.analyzing')}
</>
) : (
<>
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
</svg>
Analyze with...
{t('importAnalysis.analyzeWith')}
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor" style={{ marginLeft: 4 }}>
<path d="M7 10l5 5 5-5z"/>
</svg>
@@ -1383,14 +1384,14 @@ const TaxonomySection: React.FC<{
)}
</div>
<span className="taxonomy-analyze-hint">
AI will suggest mappings from new to existing items to avoid duplicates
{t('importAnalysis.aiMappingHint')}
</span>
</div>
{categories.length > 0 && (
<div style={{ marginBottom: 12, marginTop: 16 }}>
<div style={{ fontSize: 11, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, color: 'var(--vscode-descriptionForeground)', marginBottom: 6 }}>
Categories
{t('importAnalysis.categories')}
</div>
<div className="import-taxonomy-list">
{categories.map((cat, idx) => (
@@ -1414,7 +1415,7 @@ const TaxonomySection: React.FC<{
{tags.length > 0 && (
<div>
<div style={{ fontSize: 11, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, color: 'var(--vscode-descriptionForeground)', marginBottom: 6 }}>
Tags
{t('importAnalysis.tags')}
</div>
<div className="import-taxonomy-list">
{tags.map((tag, idx) => (
@@ -1453,6 +1454,7 @@ const TaxonomyPill: React.FC<{
onCancelEdit: () => void;
onClearMapping: () => void;
}> = ({ item, type: _type, isEditing, editValue, suggestions, onEditValueChange, onStartEdit, onSaveEdit, onCancelEdit, onClearMapping }) => {
const { t } = useI18n();
const inputRef = useRef<HTMLInputElement>(null);
const dropdownRef = useRef<HTMLDivElement>(null);
const [selectedIndex, setSelectedIndex] = useState(-1);
@@ -1536,7 +1538,7 @@ const TaxonomyPill: React.FC<{
onKeyDown={handleKeyDown}
onBlur={handleBlur}
onFocus={() => setShowDropdown(true)}
placeholder="Map to..."
placeholder={t('importAnalysis.mapToPlaceholder')}
/>
{showDropdown && filteredSuggestions.length > 0 && (
<div className="pill-suggestions-dropdown" ref={dropdownRef}>
@@ -1564,7 +1566,13 @@ const TaxonomyPill: React.FC<{
const className = `import-taxonomy-pill ${item.existsInProject ? 'exists' : 'new-tax'} ${hasMaping ? 'mapped' : ''}`;
return (
<span className={className} onClick={onStartEdit} title={`Click to ${hasMaping ? 'edit' : 'add'} mapping`}>
<span
className={className}
onClick={onStartEdit}
title={t('importAnalysis.mappingTooltip', {
action: hasMaping ? t('importAnalysis.mappingActionEdit') : t('importAnalysis.mappingActionAdd'),
})}
>
{item.name}
{hasMaping && (
<>
@@ -1573,7 +1581,7 @@ const TaxonomyPill: React.FC<{
<button
className="pill-clear-btn"
onClick={(e) => { e.stopPropagation(); onClearMapping(); }}
title="Clear mapping"
title={t('importAnalysis.clearMapping')}
>
×
</button>
@@ -1592,6 +1600,7 @@ const MacrosSection: React.FC<{
expanded: boolean;
onToggle: () => void;
}> = ({ macros, expanded, onToggle }) => {
const { t } = useI18n();
const [expandedMacros, setExpandedMacros] = useState<Set<string>>(new Set());
const toggleMacro = (name: string) => {
@@ -1610,11 +1619,11 @@ const MacrosSection: React.FC<{
<div className="import-detail-section">
<h3 onClick={onToggle}>
<span className={`toggle-icon ${expanded ? 'open' : ''}`}>&#9654;</span>
Macros ({macros.total})
{t('importAnalysis.macrosWithCount', { count: macros.total })}
<span className="macro-summary-counts">
<span className="mapped-count">{macros.mappedCount} mapped</span>
<span className="mapped-count">{t('importAnalysis.mappedCount', { count: macros.mappedCount })}</span>
{macros.unmappedCount > 0 && (
<span className="unmapped-count">{macros.unmappedCount} unmapped</span>
<span className="unmapped-count">{t('importAnalysis.unmappedCount', { count: macros.unmappedCount })}</span>
)}
</span>
</h3>
@@ -1626,15 +1635,22 @@ const MacrosSection: React.FC<{
<span className={`toggle-icon small ${expandedMacros.has(macro.name) ? 'open' : ''}`}>&#9654;</span>
<span className="macro-name">[{macro.name}]</span>
<span className={`macro-status-badge ${macro.mapped ? 'mapped' : 'unmapped'}`}>
{macro.mapped ? 'Mapped' : 'Unknown'}
{macro.mapped ? t('importAnalysis.macroStatusMapped') : t('importAnalysis.macroStatusUnknown')}
</span>
<span className="macro-count">{macro.totalCount} uses</span>
<span className="macro-count">{t('importAnalysis.macroUses', { count: macro.totalCount })}</span>
</div>
{expandedMacros.has(macro.name) && (
<div className="macro-usages">
<div className="macro-usages-header">
<span className="macro-posts-label">Used in: {macro.postSlugs.slice(0, 5).join(', ')}{macro.postSlugs.length > 5 ? `, +${macro.postSlugs.length - 5} more` : ''}</span>
<span className="macro-posts-label">
{t('importAnalysis.usedIn', {
items: macro.postSlugs.slice(0, 5).join(', '),
more: macro.postSlugs.length > 5
? t('importAnalysis.moreSuffix', { count: macro.postSlugs.length - 5 })
: '',
})}
</span>
</div>
<div className="macro-usages-list">
@@ -1646,7 +1662,7 @@ const MacrosSection: React.FC<{
>
<div className="macro-usage-params">
{Object.keys(usage.params).length === 0 ? (
<span className="no-params">(no parameters)</span>
<span className="no-params">{t('importAnalysis.noParameters')}</span>
) : (
Object.entries(usage.params).map(([key, value]) => (
<span key={key} className="macro-param">

View File

@@ -329,7 +329,7 @@ export const SettingsView: React.FC = () => {
};
const handleBrowseDataPath = async () => {
const selected = await window.electronAPI?.app.selectFolder('Select Project Data Folder');
const selected = await window.electronAPI?.app.selectFolder(t('settings.project.selectDataFolder'));
if (selected) {
setProjectDataPath(selected);
}
@@ -668,7 +668,7 @@ export const SettingsView: React.FC = () => {
<SettingSection
id="settings-section-content"
title={t('settings.content.title')}
description="Manage the available categories for blog posts. Each post can have one category that determines its display template."
description={t('settings.content.description')}
hidden={!sectionHasMatches(contentKeywords)}
>
<div className="categories-list">
@@ -677,12 +677,12 @@ export const SettingsView: React.FC = () => {
const setting = categorySettings[cat] || { renderInLists: true, showTitle: true };
return (
<div key={cat} className="category-item">
<span className="category-name">{cat}{isProtected && ' (standard)'}</span>
<span className="category-name">{cat}{isProtected && t('settings.content.standardSuffix')}</span>
<div className="category-settings-controls">
<label className="category-setting-toggle" htmlFor={`category-${cat}-render-in-lists`}>
<input
id={`category-${cat}-render-in-lists`}
aria-label={`${cat} render in lists`}
aria-label={t('settings.content.renderInListsAria', { category: cat })}
type="checkbox"
checked={setting.renderInLists}
onChange={(event) => handleCategorySettingToggle(cat, 'renderInLists', event.target.checked)}
@@ -692,7 +692,7 @@ export const SettingsView: React.FC = () => {
<label className="category-setting-toggle" htmlFor={`category-${cat}-show-title`}>
<input
id={`category-${cat}-show-title`}
aria-label={`${cat} show titles`}
aria-label={t('settings.content.showTitlesAria', { category: cat })}
type="checkbox"
checked={setting.showTitle}
onChange={(event) => handleCategorySettingToggle(cat, 'showTitle', event.target.checked)}
@@ -704,7 +704,7 @@ export const SettingsView: React.FC = () => {
<button
className="category-remove"
onClick={() => handleRemoveCategory(cat)}
title={`Remove "${cat}" category`}
title={t('settings.content.removeCategoryTitle', { category: cat })}
>
</button>
@@ -808,7 +808,7 @@ export const SettingsView: React.FC = () => {
<SettingSection
id="settings-section-ai"
title={t('settings.ai.title')}
description="Configure the AI chat assistant that helps you manage your blog content."
description={t('settings.ai.description')}
hidden={!sectionHasMatches(aiKeywords)}
>
<SettingRow
@@ -1059,8 +1059,8 @@ export const SettingsView: React.FC = () => {
<SettingRow
id="rebuild-media"
label="Rebuild Media Database"
description="Re-scan all media files and sidecar metadata. Regenerates missing entries."
label={t('settings.data.rebuildMediaLabel')}
description={t('settings.data.rebuildMediaDescription')}
>
<button
className="secondary"
@@ -1080,14 +1080,14 @@ export const SettingsView: React.FC = () => {
}
}}
>
Rebuild Media
{t('settings.data.rebuildMediaAction')}
</button>
</SettingRow>
<SettingRow
id="rebuild-links"
label="Rebuild Post Links"
description="Re-scan all posts and rebuild the internal link graph between posts."
label={t('settings.data.rebuildLinksLabel')}
description={t('settings.data.rebuildLinksDescription')}
>
<button
className="secondary"
@@ -1103,14 +1103,14 @@ export const SettingsView: React.FC = () => {
}
}}
>
Rebuild Links
{t('settings.data.rebuildLinksAction')}
</button>
</SettingRow>
<SettingRow
id="regenerate-thumbnails"
label="Regenerate Thumbnails"
description="Generate missing thumbnails for all images. Useful after importing media externally."
label={t('settings.data.regenerateThumbnailsLabel')}
description={t('settings.data.regenerateThumbnailsDescription')}
>
<button
className="secondary"
@@ -1132,20 +1132,20 @@ export const SettingsView: React.FC = () => {
}
}}
>
Generate Thumbnails
{t('settings.data.regenerateThumbnailsAction')}
</button>
</SettingRow>
</SettingSection>
<SettingSection
title={t('settings.data.fileSystemTitle')}
description="Access project data files and directories."
description={t('settings.data.fileSystemDescription')}
hidden={!sectionHasMatches(dataKeywords)}
>
<SettingRow
id="open-data"
label="Open Data Folder"
description="Open the project data folder containing posts, media, and database files."
label={t('settings.data.openDataFolderLabel')}
description={t('settings.data.openDataFolderDescription')}
>
<button
className="secondary"
@@ -1156,7 +1156,7 @@ export const SettingsView: React.FC = () => {
}
}}
>
Open Folder
{t('settings.data.openFolderAction')}
</button>
</SettingRow>
</SettingSection>

View File

@@ -571,6 +571,12 @@
"settings.content.newCategoryPlaceholder": "Neuer Kategoriename...",
"settings.content.addCategory": "Kategorie hinzufügen",
"settings.content.resetDefaults": "Auf Standard zurücksetzen",
"settings.content.description": "Verwalte die verfügbaren Kategorien für Blogbeiträge. Jeder Beitrag kann genau eine Kategorie haben, die seine Darstellungsvorlage bestimmt.",
"settings.content.standardSuffix": " (Standard)",
"settings.content.renderInListsAria": "{category} in Listen anzeigen",
"settings.content.showTitlesAria": "{category} Titel anzeigen",
"settings.content.removeCategoryTitle": "Kategorie \"{category}\" entfernen",
"settings.ai.description": "Konfiguriere den KI-Chat-Assistenten, der dir bei der Verwaltung deiner Bloginhalte hilft.",
"settings.ai.apiKeyLabel": "OpenCode-API-Schlüssel",
"settings.ai.apiKeyDescription": "Dein API-Schlüssel für das OpenCode-Zen-Gateway. Für KI-Funktionen erforderlich.",
"settings.ai.apiKeyConfigured": "API-Schlüssel konfiguriert",
@@ -595,6 +601,19 @@
"settings.data.rebuildPostsLabel": "Beitragsdatenbank neu aufbauen",
"settings.data.rebuildPostsDescription": "Alle Markdown-Beiträge neu scannen und den Datenbankindex neu aufbauen.",
"settings.data.rebuildPostsAction": "Beiträge neu aufbauen",
"settings.data.rebuildMediaLabel": "Mediendatenbank neu aufbauen",
"settings.data.rebuildMediaDescription": "Alle Mediendateien und Sidecar-Metadaten neu scannen. Fehlende Einträge werden neu erzeugt.",
"settings.data.rebuildMediaAction": "Medien neu aufbauen",
"settings.data.rebuildLinksLabel": "Beitragslinks neu aufbauen",
"settings.data.rebuildLinksDescription": "Alle Beiträge neu scannen und den internen Linkgraphen zwischen Beiträgen neu aufbauen.",
"settings.data.rebuildLinksAction": "Links neu aufbauen",
"settings.data.regenerateThumbnailsLabel": "Vorschaubilder neu erzeugen",
"settings.data.regenerateThumbnailsDescription": "Fehlende Vorschaubilder für alle Bilder erzeugen. Nützlich nach externem Medienimport.",
"settings.data.regenerateThumbnailsAction": "Vorschaubilder erzeugen",
"settings.data.fileSystemDescription": "Auf Projektdaten und Verzeichnisse zugreifen.",
"settings.data.openDataFolderLabel": "Datenordner öffnen",
"settings.data.openDataFolderDescription": "Den Projektdatenordner mit Beiträgen, Medien und Datenbankdateien öffnen.",
"settings.data.openFolderAction": "Ordner öffnen",
"sidebar.chat.header": "KI-ASSISTENT",
"sidebar.chat.newChat": "Neuer Chat",
"sidebar.chat.apiKeyNeeded": "API-Schlüssel erforderlich. Öffne einen Chat zur Konfiguration.",
@@ -767,5 +786,22 @@
"importAnalysis.existingMatch": "Vorhandene Übereinstimmung",
"importAnalysis.none": "--",
"importAnalysis.filename": "Dateiname",
"importAnalysis.path": "Pfad"
"importAnalysis.path": "Pfad",
"importAnalysis.taxonomyTitle": "Kategorien & Tags",
"importAnalysis.mappedCount": "{count} zugeordnet",
"importAnalysis.analyzeWith": "Analysieren mit...",
"importAnalysis.aiMappingHint": "KI schlägt Zuordnungen von neuen zu vorhandenen Einträgen vor, um Duplikate zu vermeiden",
"importAnalysis.mapToPlaceholder": "Zuordnen zu...",
"importAnalysis.mappingTooltip": "Klicken, um Zuordnung zu {action}",
"importAnalysis.mappingActionEdit": "bearbeiten",
"importAnalysis.mappingActionAdd": "hinzuzufügen",
"importAnalysis.clearMapping": "Zuordnung entfernen",
"importAnalysis.macrosWithCount": "Makros ({count})",
"importAnalysis.unmappedCount": "{count} nicht zugeordnet",
"importAnalysis.macroStatusMapped": "Zugeordnet",
"importAnalysis.macroStatusUnknown": "Unbekannt",
"importAnalysis.macroUses": "{count} Verwendungen",
"importAnalysis.usedIn": "Verwendet in: {items}{more}",
"importAnalysis.moreSuffix": ", +{count} weitere",
"importAnalysis.noParameters": "(keine Parameter)"
}

View File

@@ -571,6 +571,12 @@
"settings.content.newCategoryPlaceholder": "New category name...",
"settings.content.addCategory": "Add Category",
"settings.content.resetDefaults": "Reset to Defaults",
"settings.content.description": "Manage the available categories for blog posts. Each post can have one category that determines its display template.",
"settings.content.standardSuffix": " (standard)",
"settings.content.renderInListsAria": "{category} render in lists",
"settings.content.showTitlesAria": "{category} show titles",
"settings.content.removeCategoryTitle": "Remove \"{category}\" category",
"settings.ai.description": "Configure the AI chat assistant that helps you manage your blog content.",
"settings.ai.apiKeyLabel": "OpenCode API Key",
"settings.ai.apiKeyDescription": "Your API key for the OpenCode Zen gateway. Required to use AI features.",
"settings.ai.apiKeyConfigured": "API key configured",
@@ -595,6 +601,19 @@
"settings.data.rebuildPostsLabel": "Rebuild Posts Database",
"settings.data.rebuildPostsDescription": "Re-scan all post markdown files and rebuild the database index.",
"settings.data.rebuildPostsAction": "Rebuild Posts",
"settings.data.rebuildMediaLabel": "Rebuild Media Database",
"settings.data.rebuildMediaDescription": "Re-scan all media files and sidecar metadata. Regenerates missing entries.",
"settings.data.rebuildMediaAction": "Rebuild Media",
"settings.data.rebuildLinksLabel": "Rebuild Post Links",
"settings.data.rebuildLinksDescription": "Re-scan all posts and rebuild the internal link graph between posts.",
"settings.data.rebuildLinksAction": "Rebuild Links",
"settings.data.regenerateThumbnailsLabel": "Regenerate Thumbnails",
"settings.data.regenerateThumbnailsDescription": "Generate missing thumbnails for all images. Useful after importing media externally.",
"settings.data.regenerateThumbnailsAction": "Generate Thumbnails",
"settings.data.fileSystemDescription": "Access project data files and directories.",
"settings.data.openDataFolderLabel": "Open Data Folder",
"settings.data.openDataFolderDescription": "Open the project data folder containing posts, media, and database files.",
"settings.data.openFolderAction": "Open Folder",
"sidebar.chat.header": "AI ASSISTANT",
"sidebar.chat.newChat": "New Chat",
"sidebar.chat.apiKeyNeeded": "API key needed. Open a chat to configure.",
@@ -767,5 +786,22 @@
"importAnalysis.existingMatch": "Existing Match",
"importAnalysis.none": "--",
"importAnalysis.filename": "Filename",
"importAnalysis.path": "Path"
"importAnalysis.path": "Path",
"importAnalysis.taxonomyTitle": "Categories & Tags",
"importAnalysis.mappedCount": "{count} mapped",
"importAnalysis.analyzeWith": "Analyze with...",
"importAnalysis.aiMappingHint": "AI will suggest mappings from new to existing items to avoid duplicates",
"importAnalysis.mapToPlaceholder": "Map to...",
"importAnalysis.mappingTooltip": "Click to {action} mapping",
"importAnalysis.mappingActionEdit": "edit",
"importAnalysis.mappingActionAdd": "add",
"importAnalysis.clearMapping": "Clear mapping",
"importAnalysis.macrosWithCount": "Macros ({count})",
"importAnalysis.unmappedCount": "{count} unmapped",
"importAnalysis.macroStatusMapped": "Mapped",
"importAnalysis.macroStatusUnknown": "Unknown",
"importAnalysis.macroUses": "{count} uses",
"importAnalysis.usedIn": "Used in: {items}{more}",
"importAnalysis.moreSuffix": ", +{count} more",
"importAnalysis.noParameters": "(no parameters)"
}

View File

@@ -571,6 +571,12 @@
"settings.content.newCategoryPlaceholder": "Nueva categoría",
"settings.content.addCategory": "Añadir categoría",
"settings.content.resetDefaults": "Restablecer valores predeterminados",
"settings.content.description": "Gestiona las categorías disponibles para las entradas del blog. Cada entrada puede tener una sola categoría que determina su plantilla de visualización.",
"settings.content.standardSuffix": " (estándar)",
"settings.content.renderInListsAria": "{category} mostrar en listas",
"settings.content.showTitlesAria": "{category} mostrar títulos",
"settings.content.removeCategoryTitle": "Eliminar categoría \"{category}\"",
"settings.ai.description": "Configura el asistente de chat con IA que te ayuda a gestionar el contenido de tu blog.",
"settings.ai.apiKeyLabel": "Clave API",
"settings.ai.apiKeyDescription": "Introduce tu clave API para habilitar funciones de IA.",
"settings.ai.apiKeyConfigured": "Clave API configurada",
@@ -595,6 +601,19 @@
"settings.data.rebuildPostsLabel": "Reconstruir índice de publicaciones",
"settings.data.rebuildPostsDescription": "Escanea todas las publicaciones y actualiza el índice de datos.",
"settings.data.rebuildPostsAction": "Reconstruir",
"settings.data.rebuildMediaLabel": "Reconstruir base de datos de medios",
"settings.data.rebuildMediaDescription": "Reescanea todos los archivos multimedia y metadatos sidecar. Regenera las entradas faltantes.",
"settings.data.rebuildMediaAction": "Reconstruir medios",
"settings.data.rebuildLinksLabel": "Reconstruir enlaces de publicaciones",
"settings.data.rebuildLinksDescription": "Reescanea todas las publicaciones y reconstruye el grafo interno de enlaces entre publicaciones.",
"settings.data.rebuildLinksAction": "Reconstruir enlaces",
"settings.data.regenerateThumbnailsLabel": "Regenerar miniaturas",
"settings.data.regenerateThumbnailsDescription": "Genera miniaturas faltantes para todas las imágenes. Útil tras importar medios externamente.",
"settings.data.regenerateThumbnailsAction": "Generar miniaturas",
"settings.data.fileSystemDescription": "Accede a los archivos y carpetas de datos del proyecto.",
"settings.data.openDataFolderLabel": "Abrir carpeta de datos",
"settings.data.openDataFolderDescription": "Abre la carpeta de datos del proyecto que contiene publicaciones, medios y archivos de base de datos.",
"settings.data.openFolderAction": "Abrir carpeta",
"sidebar.chat.header": "Chat",
"sidebar.chat.newChat": "Nuevo chat",
"sidebar.chat.apiKeyNeeded": "Se necesita una clave API para usar el chat.",
@@ -767,5 +786,22 @@
"importAnalysis.existingMatch": "Coincidencia existente",
"importAnalysis.none": "--",
"importAnalysis.filename": "Nombre de archivo",
"importAnalysis.path": "Ruta"
"importAnalysis.path": "Ruta",
"importAnalysis.taxonomyTitle": "Categorías y Etiquetas",
"importAnalysis.mappedCount": "{count} mapeados",
"importAnalysis.analyzeWith": "Analizar con...",
"importAnalysis.aiMappingHint": "La IA sugerirá mapeos de elementos nuevos a existentes para evitar duplicados",
"importAnalysis.mapToPlaceholder": "Mapear a...",
"importAnalysis.mappingTooltip": "Haz clic para {action} el mapeo",
"importAnalysis.mappingActionEdit": "editar",
"importAnalysis.mappingActionAdd": "agregar",
"importAnalysis.clearMapping": "Borrar mapeo",
"importAnalysis.macrosWithCount": "Macros ({count})",
"importAnalysis.unmappedCount": "{count} sin mapear",
"importAnalysis.macroStatusMapped": "Mapeado",
"importAnalysis.macroStatusUnknown": "Desconocido",
"importAnalysis.macroUses": "{count} usos",
"importAnalysis.usedIn": "Usado en: {items}{more}",
"importAnalysis.moreSuffix": ", +{count} más",
"importAnalysis.noParameters": "(sin parámetros)"
}

View File

@@ -571,6 +571,12 @@
"settings.content.newCategoryPlaceholder": "Nouvelle catégorie",
"settings.content.addCategory": "Ajouter une catégorie",
"settings.content.resetDefaults": "Réinitialiser par défaut",
"settings.content.description": "Gérez les catégories disponibles pour les articles du blog. Chaque article peut avoir une seule catégorie qui détermine son modèle daffichage.",
"settings.content.standardSuffix": " (standard)",
"settings.content.renderInListsAria": "{category} afficher dans les listes",
"settings.content.showTitlesAria": "{category} afficher les titres",
"settings.content.removeCategoryTitle": "Supprimer la catégorie \"{category}\"",
"settings.ai.description": "Configurez lassistant de chat IA qui vous aide à gérer le contenu de votre blog.",
"settings.ai.apiKeyLabel": "Clé API",
"settings.ai.apiKeyDescription": "Saisissez votre clé API pour activer les fonctionnalités IA.",
"settings.ai.apiKeyConfigured": "Clé API configurée",
@@ -595,6 +601,19 @@
"settings.data.rebuildPostsLabel": "Reconstruire les index des articles",
"settings.data.rebuildPostsDescription": "Analyse tous les articles et met à jour lindex de données.",
"settings.data.rebuildPostsAction": "Reconstruire",
"settings.data.rebuildMediaLabel": "Reconstruire la base médias",
"settings.data.rebuildMediaDescription": "Réanalyse tous les fichiers médias et leurs métadonnées sidecar. Régénère les entrées manquantes.",
"settings.data.rebuildMediaAction": "Reconstruire les médias",
"settings.data.rebuildLinksLabel": "Reconstruire les liens darticles",
"settings.data.rebuildLinksDescription": "Réanalyse tous les articles et reconstruit le graphe interne des liens entre articles.",
"settings.data.rebuildLinksAction": "Reconstruire les liens",
"settings.data.regenerateThumbnailsLabel": "Régénérer les miniatures",
"settings.data.regenerateThumbnailsDescription": "Génère les miniatures manquantes pour toutes les images. Utile après un import média externe.",
"settings.data.regenerateThumbnailsAction": "Générer les miniatures",
"settings.data.fileSystemDescription": "Accédez aux fichiers et dossiers de données du projet.",
"settings.data.openDataFolderLabel": "Ouvrir le dossier de données",
"settings.data.openDataFolderDescription": "Ouvrez le dossier de données du projet contenant articles, médias et fichiers de base de données.",
"settings.data.openFolderAction": "Ouvrir le dossier",
"sidebar.chat.header": "Chat",
"sidebar.chat.newChat": "Nouveau chat",
"sidebar.chat.apiKeyNeeded": "Une clé API est nécessaire pour utiliser le chat.",
@@ -767,5 +786,22 @@
"importAnalysis.existingMatch": "Correspondance existante",
"importAnalysis.none": "--",
"importAnalysis.filename": "Nom de fichier",
"importAnalysis.path": "Chemin"
"importAnalysis.path": "Chemin",
"importAnalysis.taxonomyTitle": "Catégories & Tags",
"importAnalysis.mappedCount": "{count} mappé(s)",
"importAnalysis.analyzeWith": "Analyser avec...",
"importAnalysis.aiMappingHint": "LIA suggère des correspondances entre nouveaux éléments et éléments existants pour éviter les doublons",
"importAnalysis.mapToPlaceholder": "Mapper vers...",
"importAnalysis.mappingTooltip": "Cliquer pour {action} le mapping",
"importAnalysis.mappingActionEdit": "modifier",
"importAnalysis.mappingActionAdd": "ajouter",
"importAnalysis.clearMapping": "Effacer le mapping",
"importAnalysis.macrosWithCount": "Macros ({count})",
"importAnalysis.unmappedCount": "{count} non mappé(s)",
"importAnalysis.macroStatusMapped": "Mappé",
"importAnalysis.macroStatusUnknown": "Inconnu",
"importAnalysis.macroUses": "{count} utilisations",
"importAnalysis.usedIn": "Utilisé dans : {items}{more}",
"importAnalysis.moreSuffix": ", +{count} de plus",
"importAnalysis.noParameters": "(aucun paramètre)"
}

View File

@@ -571,6 +571,12 @@
"settings.content.newCategoryPlaceholder": "Nuova categoria",
"settings.content.addCategory": "Aggiungi categoria",
"settings.content.resetDefaults": "Ripristina predefiniti",
"settings.content.description": "Gestisci le categorie disponibili per i post del blog. Ogni post può avere una sola categoria che ne determina il template di visualizzazione.",
"settings.content.standardSuffix": " (standard)",
"settings.content.renderInListsAria": "{category} mostra negli elenchi",
"settings.content.showTitlesAria": "{category} mostra i titoli",
"settings.content.removeCategoryTitle": "Rimuovi la categoria \"{category}\"",
"settings.ai.description": "Configura lassistente chat IA che ti aiuta a gestire i contenuti del tuo blog.",
"settings.ai.apiKeyLabel": "Chiave API",
"settings.ai.apiKeyDescription": "Inserisci la tua chiave API per abilitare le funzioni IA.",
"settings.ai.apiKeyConfigured": "Chiave API configurata",
@@ -595,6 +601,19 @@
"settings.data.rebuildPostsLabel": "Ricostruisci indice articoli",
"settings.data.rebuildPostsDescription": "Analizza tutti gli articoli e aggiorna lindice dati.",
"settings.data.rebuildPostsAction": "Ricostruisci",
"settings.data.rebuildMediaLabel": "Ricostruisci database media",
"settings.data.rebuildMediaDescription": "Rianalizza tutti i file media e i metadati sidecar. Rigenera le voci mancanti.",
"settings.data.rebuildMediaAction": "Ricostruisci media",
"settings.data.rebuildLinksLabel": "Ricostruisci collegamenti post",
"settings.data.rebuildLinksDescription": "Rianalizza tutti i post e ricostruisce il grafo interno dei collegamenti tra post.",
"settings.data.rebuildLinksAction": "Ricostruisci collegamenti",
"settings.data.regenerateThumbnailsLabel": "Rigenera miniature",
"settings.data.regenerateThumbnailsDescription": "Genera le miniature mancanti per tutte le immagini. Utile dopo limportazione esterna dei media.",
"settings.data.regenerateThumbnailsAction": "Genera miniature",
"settings.data.fileSystemDescription": "Accedi ai file e alle cartelle dati del progetto.",
"settings.data.openDataFolderLabel": "Apri cartella dati",
"settings.data.openDataFolderDescription": "Apri la cartella dati del progetto contenente post, media e file del database.",
"settings.data.openFolderAction": "Apri cartella",
"sidebar.chat.header": "Chat",
"sidebar.chat.newChat": "Nuova chat",
"sidebar.chat.apiKeyNeeded": "Serve una chiave API per usare la chat.",
@@ -767,5 +786,22 @@
"importAnalysis.existingMatch": "Corrispondenza esistente",
"importAnalysis.none": "--",
"importAnalysis.filename": "Nome file",
"importAnalysis.path": "Percorso"
"importAnalysis.path": "Percorso",
"importAnalysis.taxonomyTitle": "Categorie & Tag",
"importAnalysis.mappedCount": "{count} mappati",
"importAnalysis.analyzeWith": "Analizza con...",
"importAnalysis.aiMappingHint": "LIA suggerirà mappature da elementi nuovi a quelli esistenti per evitare duplicati",
"importAnalysis.mapToPlaceholder": "Mappa a...",
"importAnalysis.mappingTooltip": "Clicca per {action} la mappatura",
"importAnalysis.mappingActionEdit": "modificare",
"importAnalysis.mappingActionAdd": "aggiungere",
"importAnalysis.clearMapping": "Cancella mappatura",
"importAnalysis.macrosWithCount": "Macro ({count})",
"importAnalysis.unmappedCount": "{count} non mappati",
"importAnalysis.macroStatusMapped": "Mappato",
"importAnalysis.macroStatusUnknown": "Sconosciuto",
"importAnalysis.macroUses": "{count} utilizzi",
"importAnalysis.usedIn": "Usato in: {items}{more}",
"importAnalysis.moreSuffix": ", +{count} altri",
"importAnalysis.noParameters": "(nessun parametro)"
}

View File

@@ -40,9 +40,32 @@ describe('Phase 1 i18n hardcoded literals', () => {
file: 'src/renderer/components/Editor/Editor.tsx',
literals: ['Save Failed', 'Post published', 'Media not found', 'title="Quick Actions"'],
},
{
file: 'src/renderer/components/SettingsView/SettingsView.tsx',
literals: [
'Manage the available categories for blog posts. Each post can have one category that determines its display template.',
'Configure the AI chat assistant that helps you manage your blog content.',
'Rebuild Media Database',
'Rebuild Post Links',
'Regenerate Thumbnails',
'Open Data Folder',
'Open Folder',
],
},
{
file: 'src/renderer/components/ImportAnalysisView/ImportAnalysisView.tsx',
literals: ['Loading import definition...', 'Import name...', 'Select & Analyze', 'Import completed successfully!'],
literals: [
'Loading import definition...',
'Import name...',
'Select & Analyze',
'Import completed successfully!',
'Categories & Tags',
'Analyze with...',
'Map to...',
'Clear mapping',
'Used in:',
'(no parameters)',
],
},
];