v0.249.0: i18n slice 1 release B — backup pages in English, Hungarian byte-identical (R-556)
gates / gates (push) Successful in 20s

Seven backup pages + the restore-progress JS converted against fixtures captured unconverted
(f8ebc47); recovery renders through executeTemplateLang; English retrieval claims registered;
the Fut comparison left unconverted (R-563).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-17 18:01:09 +02:00
parent f8ebc47728
commit 11b790e314
24 changed files with 2921 additions and 433 deletions
@@ -8,8 +8,8 @@
<div class="page-header">
<div style="display:flex;align-items:center;gap:.5rem">
<a href="/backups/restore" class="btn btn-sm btn-outline">← Vissza</a>
<h2>Visszaállítás — {{.AppDisplayName}}</h2>
<a href="/backups/restore" class="btn btn-sm btn-outline">{{T "backups_restore_wizard.vissza"}}</a>
<h2>{{T "backups_restore_wizard.visszaallitas"}}</h2>
</div>
<span class="domain-badge">{{.Domain}}</span>
</div>
@@ -22,19 +22,19 @@
with nothing signposting that a second step existed at all. -->
{{$phase := printf "%s" .Wizard.Phase}}
<div class="restore-wizard-phases">
<span class="restore-wizard-phase{{if eq $phase "elokeszites"}} is-current{{end}}">Előkészítés</span>
<span class="restore-wizard-phase{{if eq $phase "megerosites"}} is-current{{end}}">Megerősítés</span>
<span class="restore-wizard-phase{{if eq $phase "vegrehajtas"}} is-current{{end}}">Végrehajtás</span>
<span class="restore-wizard-phase{{if eq $phase "eredmeny"}} is-current{{end}}">Eredmény</span>
<span class="restore-wizard-phase{{if eq $phase "elokeszites"}} is-current{{end}}">{{T "backups_restore_wizard.elokeszites"}}</span>
<span class="restore-wizard-phase{{if eq $phase "megerosites"}} is-current{{end}}">{{T "backups_restore_wizard.megerosites"}}</span>
<span class="restore-wizard-phase{{if eq $phase "vegrehajtas"}} is-current{{end}}">{{T "backups_restore_wizard.vegrehajtas"}}</span>
<span class="restore-wizard-phase{{if eq $phase "eredmeny"}} is-current{{end}}">{{T "backups_restore_wizard.eredmeny"}}</span>
</div>
{{with .LastResult}}
<!-- „Eredmény": the outcome of the restore that just finished, for THIS app. The redirect flash says
the same thing but does not survive a reload; this does, for restoreResultWindow. -->
<div class="settings-card">
<h3>Eredmény</h3>
<h3>{{T "backups_restore_wizard.eredmeny"}}</h3>
<div class="alert {{if .OK}}alert-info{{else}}alert-error{{end}}">{{.Message}}</div>
<p class="form-hint">{{if .Interrupted}}Észlelve{{else}}Befejezve{{end}}: {{fmtTime .FinishedAt}}. Ha szeretnéd, alább újra indíthatsz egy visszaállítást.</p>
<p class="form-hint">{{if .Interrupted}}{{T "backups_restore_wizard.eszlelve"}}{{else}}{{T "backups_restore_wizard.befejezve"}}{{end}}{{T "backups_restore_wizard.ha_szeretned_alabb_ujra_indithatsz"}}</p>
</div>
{{end}}
@@ -43,15 +43,15 @@
refuse them anyway; offering a control guaranteed to fail is the same dishonesty class R-48
addresses. The live progress comes from the existing restore-status poll (the banner above). -->
<div class="settings-card">
<h3>Végrehajtás</h3>
<p>Jelenleg egy mentési vagy visszaállítási művelet fut{{with .RunningStack}} ({{.}}){{end}}. Amíg ez tart, új visszaállítás nem indítható.</p>
<h3>{{T "backups_restore_wizard.vegrehajtas"}}</h3>
<p>{{T "backups_restore_wizard.jelenleg_egy_mentesi_vagy_visszaallitasi"}}{{with .RunningStack}} ({{.}}){{end}}{{T "backups_restore_wizard.amig_ez_tart_uj_visszaallitas"}}</p>
<!-- R-351: this used to say the state refreshes automatically AND that you must refresh the page
when it finishes. Both cannot be true, and the second half was the one people believed. The
banner now carries the terminal result too (RestoreOpStatus.LastRecent), so the sentence can
describe what the page actually does. -->
<p class="form-hint">Az állapot fent automatikusan frissül, és a művelet eredménye is ott jelenik meg, amint elkészült.</p>
<p class="form-hint">{{T "backups_restore_wizard.az_allapot_fent_automatikusan_frissul"}}</p>
<div class="form-actions">
<a href="/backups/restore/app?name={{.App}}" class="btn btn-sm btn-outline">Állapot frissítése</a>
<a href="/backups/restore/app?name={{.App}}" class="btn btn-sm btn-outline">{{T "backups_restore_wizard.allapot_frissitese"}}</a>
</div>
</div>
@@ -59,17 +59,17 @@
<!-- MEGERŐSÍTÉS — the size gate. The preparation has measured what needs downloading; the customer
confirms with the size in front of them, before any transfer starts. -->
<div class="settings-card">
<h3>Megerősítés — teljes visszaállítás előkészítése</h3>
<p>A teljes visszaállításhoz a mentés teljes tartalmát le kell tölteni a távoli tárolóból{{with .FullPrepSize}} — a becsült méret: <strong>{{.}}</strong>{{end}}. A letöltés a meghajtón egy külön előkészítő mappába kerül; az élő adataid ebben a lépésben még nem változnak.</p>
<p class="form-hint">A letöltés a mérettől és a kapcsolat sebességétől függően hosszabb ideig is tarthat. Ha elkészült, ezen az oldalon választhatod ki, hogy csak a hiányzó fájlokat hozod vissza, vagy teljes visszaállítást kérsz.</p>
<h3>{{T "backups_restore_wizard.megerosites_teljes_visszaallitas_elokesz"}}</h3>
<p>{{T "backups_restore_wizard.a_teljes_visszaallitashoz_a_mentes"}}{{with .FullPrepSize}} {{T "backups_restore_wizard.a_becsult_meret"}}{{end}}{{T "backups_restore_wizard.a_letoltes_a_meghajton_egy"}}</p>
<p class="form-hint">{{T "backups_restore_wizard.a_letoltes_a_merettol_es"}}</p>
<div class="form-actions">
<form method="POST" action="/backup/offbox/restore">{{.CSRFField}}
<input type="hidden" name="app" value="{{.App}}">
<input type="hidden" name="mode" value="full">
<input type="hidden" name="confirm" value="1">
<button type="submit" class="btn btn-primary">Előkészítés indítása{{with .FullPrepSize}} (~{{.}}){{end}}</button>
<button type="submit" class="btn btn-primary">{{T "backups_restore_wizard.elokeszites_inditasa"}}{{with .FullPrepSize}} (~{{.}}){{end}}</button>
</form>
<a href="/backups/restore/app?name={{.App}}" class="btn btn-outline">Mégsem</a>
<a href="/backups/restore/app?name={{.App}}" class="btn btn-outline">{{T "backups_restore_wizard.megsem"}}</a>
</div>
</div>
@@ -78,52 +78,52 @@
harmless first, irreversible-looking last. -->
<div class="settings-card">
<h3>1. Ellenőrzés külön mappába (beállítások és adatbázis)</h3>
<h3>{{T "backups_restore_wizard.1_ellenorzes_kulon_mappaba_beallitasok"}}</h3>
<!-- R-204 item 3: this card's scope is stated BEFORE the choice, not only in the outcome. It
restores the recovery unit only; the customer's own files stay in the backup. Saying „a
mentés tartalma" here was how a disaster-recovery customer chose the one intent that does
not return their documents. -->
<p>Az alkalmazás beállításait és adatbázisát hozza vissza egy külön ellenőrző mappába. A saját fájljaidat (dokumentumok, képek, feltöltések) <strong>nem</strong> hozza vissza — azokhoz a 3. pont teljes visszaállítása kell. Az élő adataid nem változnak.</p>
<p>{{T "backups_restore_wizard.az_alkalmazas_beallitasait_es_adatbazisa"}}</p>
<div class="form-actions">
<form method="POST" action="/backup/offbox/restore">{{.CSRFField}}
<input type="hidden" name="app" value="{{.App}}">
<input type="hidden" name="mode" value="unit">
<button type="submit" class="btn btn-outline"{{if not .Wizard.VerifyEnabled}} disabled{{end}}>Ellenőrzés indítása</button>
<button type="submit" class="btn btn-outline"{{if not .Wizard.VerifyEnabled}} disabled{{end}}>{{T "backups_restore_wizard.ellenorzes_inditasa"}}</button>
</form>
</div>
</div>
<div class="settings-card">
<h3>2. Hiányzó fájlok visszahozása</h3>
<p>Csak a hiányzó fájlokat másolja vissza a meglévők közé. A meglévő fájlokat nem írja felül, adatbázist nem állít vissza — törölt tartalom ettől nem jelenik meg újra.</p>
<h3>{{T "backups_restore_wizard.2_hianyzo_fajlok_visszahozasa"}}</h3>
<p>{{T "backups_restore_wizard.csak_a_hianyzo_fajlokat_masolja"}}</p>
{{if .Wizard.PlaceEnabled}}
<div class="form-actions">
<form method="POST" action="/backup/offbox/place">{{.CSRFField}}
<input type="hidden" name="app" value="{{.App}}">
<button type="submit" class="btn btn-outline">Hiányzó fájlok visszahozása</button>
<button type="submit" class="btn btn-outline">{{T "backups_restore_wizard.hianyzo_fajlok_visszahozasa"}}</button>
</form>
</div>
{{else}}
<p class="form-hint">Ehhez előbb elő kell készíteni a teljes mentést — lásd a 3. pontot.</p>
<p class="form-hint">{{T "backups_restore_wizard.ehhez_elobb_elo_kell_kesziteni"}}</p>
{{end}}
</div>
<div class="settings-card restore-danger-card">
<h3>3. Teljes visszaállítás (fájlok + adatbázis)</h3>
<p>A fájlokat a mentés szerinti változatra állítja vissza és az adatbázist is visszatölti. Semmit nem töröl: a mentés óta létrejött fájlok megmaradnak. A jelenlegi adatbázisról előtte biztonsági mentés készül.</p>
<h3>{{T "backups_restore_wizard.3_teljes_visszaallitas_fajlok_adatbazis"}}</h3>
<p>{{T "backups_restore_wizard.a_fajlokat_a_mentes_szerinti"}}</p>
{{if .Wizard.RestoreEnabled}}
<!-- Pair honesty (R-43): what the two halves of this restore actually ARE. A restore is the one
operation whose result cannot be inspected before committing to it. -->
<div class="alert alert-info" style="margin-bottom:.75rem">
<strong>Az előkészített mentés:</strong>
{{if not .Pair.DumpsAt.IsZero}}adatbázis-mentés ideje: {{fmtTime .Pair.DumpsAt}}.{{else}}az adatbázis-mentés ideje nem állapítható meg.{{end}}
<strong>{{T "backups_restore_wizard.az_elokeszitett_mentes"}}</strong>
{{if not .Pair.DumpsAt.IsZero}}{{T "backups_restore_wizard.adatbazis_mentes_ideje"}}{{else}}{{T "backups_restore_wizard.az_adatbazis_mentes_ideje_nem"}}{{end}}
</div>
{{if .Pair.Skewed}}
<div class="alert alert-warning" style="margin-bottom:.75rem">Az adatbázis-mentés régebbi{{if not .Pair.DumpsAt.IsZero}} ({{fmtTime .Pair.DumpsAt}}){{end}} — a fájlok és az adatbázis eltérő időpontból származnak.</div>
<div class="alert alert-warning" style="margin-bottom:.75rem">{{T "backups_restore_wizard.az_adatbazis_mentes_regebbi"}}{{if not .Pair.DumpsAt.IsZero}} ({{fmtTime .Pair.DumpsAt}}){{end}} {{T "backups_restore_wizard.a_fajlok_es_az_adatbazis"}}</div>
{{end}}
{{if .Pair.LooksEmpty}}
<div class="alert alert-warning" style="margin-bottom:.75rem">A mentett adatbázis üresnek tűnik (nincs benne felhasználói fiók) — elképzelhető, hogy a mentés korábbi, mint az adataid.</div>
<div class="alert alert-warning" style="margin-bottom:.75rem">{{T "backups_restore_wizard.a_mentett_adatbazis_uresnek_tunik"}}</div>
{{end}}
<div class="form-actions">
<form method="POST" action="/backup/offbox/reconstitute">{{.CSRFField}}
@@ -134,16 +134,16 @@
data-restore-when="{{if not .Pair.DumpsAt.IsZero}}{{fmtTime .Pair.DumpsAt}}{{end}}"
data-restore-skewed="{{if .Pair.Skewed}}1{{end}}"
data-restore-empty="{{if .Pair.LooksEmpty}}1{{end}}"
onclick="confirmFullRestore(this)">Teljes visszaállítás indítása</button>
onclick="confirmFullRestore(this)">{{T "backups_restore_wizard.teljes_visszaallitas_inditasa"}}</button>
</form>
</div>
{{else}}
<p class="form-hint">A teljes visszaállításhoz először le kell tölteni a mentés teljes tartalmát. Az előkészítés megmutatja a méretet, mielőtt bármi elindulna — az élő adataid az előkészítés alatt nem változnak.</p>
<p class="form-hint">{{T "backups_restore_wizard.a_teljes_visszaallitashoz_eloszor_le"}}</p>
<div class="form-actions">
<form method="POST" action="/backup/offbox/restore">{{.CSRFField}}
<input type="hidden" name="app" value="{{.App}}">
<input type="hidden" name="mode" value="full">
<button type="submit" class="btn btn-outline"{{if not .Wizard.PrepareEnabled}} disabled{{end}}>Teljes visszaállítás előkészítése</button>
<button type="submit" class="btn btn-outline"{{if not .Wizard.PrepareEnabled}} disabled{{end}}>{{T "backups_restore_wizard.teljes_visszaallitas_elokeszitese"}}</button>
</form>
</div>
{{end}}
@@ -162,12 +162,12 @@ function confirmFullRestore(btn){
var when = btn.getAttribute('data-restore-when') || '';
var skewed = btn.getAttribute('data-restore-skewed') === '1';
var empty = btn.getAttribute('data-restore-empty') === '1';
var q = 'Teljes visszaállítás: ' + app + (when ? ' — a mentés ideje: ' + when : '') + '.';
if (skewed) { q += ' FIGYELEM: a fájlok és az adatbázis eltérő időpontból származnak.'; }
if (empty) { q += ' FIGYELEM: a mentett adatbázis üresnek tűnik.'; }
q += ' A fájlok a mentés szerinti változatra állnak vissza, semmi nem törlődik.';
var q = '{{T "backups_restore_wizard.teljes_visszaallitas"}} ' + app + (when ? ' {{T "backups_restore_wizard.a_mentes_ideje"}} ' + when : '') + '.';
if (skewed) { q += ' {{T "backups_restore_wizard.figyelem_a_fajlok_es_az"}}'; }
if (empty) { q += ' {{T "backups_restore_wizard.figyelem_a_mentett_adatbazis_uresnek"}}'; }
q += ' {{T "backups_restore_wizard.a_fajlok_a_mentes_szerinti"}}';
felhomConfirm(btn, q, function(){
felhomConfirm(btn, 'UTOLSÓ MEGERŐSÍTÉS: az alkalmazás leáll, az adatbázis visszatöltődik, majd újraindul. A jelenlegi adatbázisról biztonsági mentés készül.', function(){
felhomConfirm(btn, '{{T "backups_restore_wizard.utolso_megerosites_az_alkalmazas_leall"}}', function(){
var f = btn.closest('form');
if (f) { if (f.requestSubmit) f.requestSubmit(); else f.submit(); }
});