Merge develop: combine the i18n test fixture with #363

Both message batches seeded locale copies at the same point of
test_command_descriptions.py. The two blocks are independent — one
seeds the backup messages, the other the storage ones — so they are
merged into a single block that reads and writes the fixture once.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
MacRimi
2026-09-22 16:46:04 +02:00
co-authored by Claude Opus 5
23 changed files with 1206 additions and 64 deletions
+3 -3
View File
@@ -1300,7 +1300,7 @@ export function HostBackup() {
</div>
) : unifiedArchives.length === 0 ? (
<div className="text-sm text-muted-foreground py-4">
{t("backup.archives.emptyBefore")} <span className="font-medium">{t("backup.manual.run")}</span> {t("backup.archives.emptyAfter")}
{t("backup.archives.emptyMessage")}
</div>
) : (
<div className="space-y-2">
@@ -4089,7 +4089,7 @@ function CreateJobDialog({
className="font-mono"
/>
<p className="text-xs text-muted-foreground">
{t("backup.destinations.localAttachHelpBefore")} <code className="font-mono">/dump</code> {t("backup.destinations.localAttachHelpMiddle")} <code className="font-mono">/var/lib/vz/dump</code>.
{t("backup.destinations.localAttachHelpMessage")}
</p>
</>
) : (
@@ -5709,7 +5709,7 @@ function DestinationsSection({
)}
{backups > 0 && (
<div className="px-3 py-2 rounded-md border border-blue-500/40 bg-blue-500/5">
{t("backup.destinations.backupsKeptBefore", { count: backups })} <span className="font-medium">{t("backup.destinations.kept")}</span>.
{t("backup.destinations.backupsKeptMessage")}
</div>
)}
</div>
+18
View File
@@ -7,4 +7,22 @@ The ProxMenux Monitor dashboard uses a small client-side i18n layer.
To improve a translation, edit the values in your locale's `common.json` — keep placeholders such as `{uptime}`, `{vmid}` or `{count}` unchanged, and don't translate brand or product names (`ProxMenux Monitor`, `Proxmox Backup Server`, `Secure Gateway`, `Tailscale`, etc.). Missing keys fall back to English at runtime, so a partial refresh is always safe to merge.
## Backup message composition regressions
From the repository root, run:
```sh
node tests/test_backup_archives_empty.cjs
node tests/test_backup_destination_messages.cjs
```
Prerequisites: Node.js and the `typescript` development dependency from
`AppImage/package.json` must be installed/resolvable (normally in
`AppImage/node_modules`). These tests compile actual JSX message branches and
pure i18n lookup functions without importing the component or calling a backend.
They cover whole English messages, missing-key locale fallback, loading/error
branches, nonempty lists, the removal notice at zero/one/multiple archives,
local-attach help, and unchanged shared labels. They do not replace browser or
real-host acceptance. Keep literal paths in the local-attach help unchanged.
To add a new locale, see [§11 → Adding a new locale](../../CONTRIBUTING.md#adding-a-new-locale) in the Contributing Guide.
+5 -2
View File
@@ -3845,7 +3845,8 @@
"restoreTitle": "Von diesem Backup wiederherstellen",
"startingExport": "Download wird vorbereitet...",
"title": "Backups",
"viewContentsTitle": "Sicherungsinhalte anzeigen"
"viewContentsTitle": "Sicherungsinhalte anzeigen",
"emptyMessage": "Keine Sicherungsarchive gefunden."
},
"backends": {
"borgDescription": "Borg-Repository für deduplizierte Host-Backups.",
@@ -3961,7 +3962,9 @@
"sshUserHelpBefore": "Benutzer auf dem Remote-Host,",
"title": "Reiseziele",
"unmountTitle": "Hängen Sie dieses Ziel aus",
"whereIsBorgRepo": "Wo ist das Borg-Repository?"
"whereIsBorgRepo": "Wo ist das Borg-Repository?",
"backupsKeptMessage": "Vorhandene Backup-Archive werden nicht gelöscht.",
"localAttachHelpMessage": "Mounten Sie zuerst USB-Laufwerke.Lassen Sie das Feld leer, um den PVE-Speicherpfad + /dump zu verwenden (Fallback: /var/lib/vz/dump)."
},
"encryption": {
"autoDetectedFromPveStorage": "Aus PVE-Speicher erkannt",
+3
View File
@@ -3835,6 +3835,7 @@
"downloadTitle": "Download this backup",
"emptyAfter": "backups yet.",
"emptyBefore": "No",
"emptyMessage": "No backup archives found.",
"encrypted": "Encrypted",
"encryptedTitle": "This backup is encrypted",
"filesInBackup": "Files in backup",
@@ -3910,6 +3911,7 @@
"addPbsRepository": "Add PBS repository",
"appendAuthorizedKeyBefore": "Append the generated public key to",
"backupsKeptBefore": "Existing backups are kept in",
"backupsKeptMessage": "Existing backup archives are not deleted.",
"borgEncryptionInherited": "Borg encryption is controlled by the repository.",
"builtIn": "Built-in",
"builtInDefault": "Built-in default",
@@ -3930,6 +3932,7 @@
"leavePassphraseBlank": "Leave blank to keep the saved passphrase.",
"leavePasswordBlank": "Leave blank to keep the saved password.",
"localAttachHelpBefore": "Use a mounted local path. For USB drives, mount them first in",
"localAttachHelpMessage": "Mount USB drives first. Leave blank to use the PVE storage path + /dump (fallback: /var/lib/vz/dump).",
"localAttachHelpMiddle": "USB drives",
"localManualPickHelp": "Pick a local path for one-shot backup output.",
"localPathHelpAfter": "or another mounted path.",
+5 -2
View File
@@ -3845,7 +3845,8 @@
"restoreTitle": "Restaurar desde esta copia de seguridad",
"startingExport": "Preparando descarga...",
"title": "Copias de seguridad",
"viewContentsTitle": "Ver contenidos de la copia de seguridad"
"viewContentsTitle": "Ver contenidos de la copia de seguridad",
"emptyMessage": "No se encontraron archivos de respaldo."
},
"backends": {
"borgDescription": "Repositorio Borg para copias de seguridad de host deduplicadas.",
@@ -3961,7 +3962,9 @@
"sshUserHelpBefore": "Usuario en el host remoto,",
"title": "Destinos",
"unmountTitle": "Desmontar este destino",
"whereIsBorgRepo": "¿Dónde está el repositorio Borg?"
"whereIsBorgRepo": "¿Dónde está el repositorio Borg?",
"backupsKeptMessage": "los archivos de copia de seguridad existentes no se eliminan.",
"localAttachHelpMessage": "Monte primero las unidades USB.Déjelo en blanco para usar la ruta de almacenamiento PVE + /dump (alternativa: /var/lib/vz/dump)."
},
"encryption": {
"autoDetectedFromPveStorage": "Detectado desde el almacenamiento PVE",
+5 -2
View File
@@ -3845,7 +3845,8 @@
"restoreTitle": "Restaurer à partir de cette sauvegarde",
"startingExport": "Préparation du téléchargement...",
"title": "Sauvegardes",
"viewContentsTitle": "Afficher le contenu de la sauvegarde"
"viewContentsTitle": "Afficher le contenu de la sauvegarde",
"emptyMessage": "Aucune archive de sauvegarde trouvée."
},
"backends": {
"borgDescription": "Référentiel Borg pour les sauvegardes d'hôtes dédupliquées.",
@@ -3961,7 +3962,9 @@
"sshUserHelpBefore": "Utilisateur sur l'hôte distant,",
"title": "Destinations",
"unmountTitle": "Démonter cette destination",
"whereIsBorgRepo": "Où se trouve le référentiel Borg ?"
"whereIsBorgRepo": "Où se trouve le référentiel Borg ?",
"backupsKeptMessage": "Les archives de sauvegarde existantes ne sont pas supprimées.",
"localAttachHelpMessage": "Montez d’abord les clés USB.Laissez vide pour utiliser le chemin de stockage PVE + /dump (repli : /var/lib/vz/dump)."
},
"encryption": {
"autoDetectedFromPveStorage": "Détecté depuis le stockage PVE",
+5 -2
View File
@@ -3845,7 +3845,8 @@
"restoreTitle": "Ripristina da questo backup",
"startingExport": "Preparazione download...",
"title": "Backup",
"viewContentsTitle": "Visualizza i contenuti del backup"
"viewContentsTitle": "Visualizza i contenuti del backup",
"emptyMessage": "nessun archivio di backup trovato."
},
"backends": {
"borgDescription": "Repository Borg per backup host deduplicati.",
@@ -3961,7 +3962,9 @@
"sshUserHelpBefore": "Utente sull'host remoto,",
"title": "Destinazioni",
"unmountTitle": "Smonta questa destinazione",
"whereIsBorgRepo": "Dov'è il deposito Borg?"
"whereIsBorgRepo": "Dov'è il deposito Borg?",
"backupsKeptMessage": "gli archivi di backup esistenti non vengono eliminati.",
"localAttachHelpMessage": "monta prima le unità USB.Lascia vuoto per utilizzare il percorso di archiviazione PVE + /dump (fallback: /var/lib/vz/dump)."
},
"encryption": {
"autoDetectedFromPveStorage": "Rilevato dall'archivio PVE",
+5 -2
View File
@@ -3845,7 +3845,8 @@
"restoreTitle": "Restaurar deste backup",
"startingExport": "Preparando download...",
"title": "Cópias de segurança",
"viewContentsTitle": "Ver o conteúdo do backup"
"viewContentsTitle": "Ver o conteúdo do backup",
"emptyMessage": "Nenhum arquivo de backup encontrado."
},
"backends": {
"borgDescription": "Repositório Borg para backups de host desduplicados.",
@@ -3961,7 +3962,9 @@
"sshUserHelpBefore": "Usuário no host remoto,",
"title": "Destinos",
"unmountTitle": "Desmontar este destino",
"whereIsBorgRepo": "Onde está o repositório Borg?"
"whereIsBorgRepo": "Onde está o repositório Borg?",
"backupsKeptMessage": "os arquivos de backup existentes não são excluídos.",
"localAttachHelpMessage": "Monte as unidades USB primeiro.Deixe em branco para usar o caminho de armazenamento PVE + /dump (fallback: /var/lib/vz/dump)."
},
"encryption": {
"autoDetectedFromPveStorage": "Detectado no armazenamento PVE",
File diff suppressed because one or more lines are too long
+5 -2
View File
@@ -3845,7 +3845,8 @@
"startingExport": "Förbereder nedladdning...",
"title": "Säkerhetskopieringar",
"viewContentsTitle": "Visa säkerhetskopieringsinnehåll",
"descriptionAfter": ""
"descriptionAfter": "",
"emptyMessage": "Inga backup-arkiv hittades."
},
"backends": {
"borgDescription": "Borg-arkiv för deduplicerade värdsäkerhetskopior.",
@@ -3961,7 +3962,9 @@
"sshUserHelpBefore": "Användare på fjärrvärden,",
"title": "Destinationer",
"unmountTitle": "Avmontera denna destination",
"whereIsBorgRepo": "Var finns Borgarkivet?"
"whereIsBorgRepo": "Var finns Borgarkivet?",
"backupsKeptMessage": "Befintliga säkerhetskopieringsarkiv tas inte bort.",
"localAttachHelpMessage": "Montera USB-enheter först.Lämna tomt för att använda PVE-lagringssökvägen + /dump (fallback: /var/lib/vz/dump)."
},
"encryption": {
"autoDetectedFromPveStorage": "Upptäckt från PVE-lagring",