diff --git a/AppImage/ProxMenux-1.2.2.3-beta.AppImage b/AppImage/ProxMenux-1.2.2.3-beta.AppImage
index 61a48343..e99bd940 100755
Binary files a/AppImage/ProxMenux-1.2.2.3-beta.AppImage and b/AppImage/ProxMenux-1.2.2.3-beta.AppImage differ
diff --git a/AppImage/ProxMenux-Monitor.AppImage.sha256 b/AppImage/ProxMenux-Monitor.AppImage.sha256
index 08f1df63..b3df5e50 100644
--- a/AppImage/ProxMenux-Monitor.AppImage.sha256
+++ b/AppImage/ProxMenux-Monitor.AppImage.sha256
@@ -1 +1 @@
-4abe67f2d2d7516c438d222ed73fb166b0f6b3b77e85e9a6be37194b4b178cdd ProxMenux-1.2.2.3-beta.AppImage
+0aab70a57567904c943f22a06120e6b01c661858754ef3adfa525dc9b8bbe07b ProxMenux-1.2.2.3-beta.AppImage
diff --git a/AppImage/components/host-backup.tsx b/AppImage/components/host-backup.tsx
index deabe18c..d1d24fb3 100644
--- a/AppImage/components/host-backup.tsx
+++ b/AppImage/components/host-backup.tsx
@@ -7718,7 +7718,7 @@ function RestoreOptionsModal({
- After the reboot, this Backups tab will show a live post-restore progress card with ETA, per-component status, log tail and rollback delta. If Telegram/Discord/ntfy notifications are configured, you'll also receive the "Host restore finished" event.
+ After the reboot, this Backups tab will show a live post-restore progress card with estimated time, per-component status, log tail and rollback delta. If Telegram/Discord/ntfy notifications are configured, you'll also receive the "Host restore finished" event.
diff --git a/AppImage/components/release-notes-modal.tsx b/AppImage/components/release-notes-modal.tsx
index cf6f98e4..248d04b0 100644
--- a/AppImage/components/release-notes-modal.tsx
+++ b/AppImage/components/release-notes-modal.tsx
@@ -222,7 +222,7 @@ const CURRENT_VERSION_FEATURES = [
},
{
icon: ,
- text: "Live post-restore progress — after a reboot the Backups tab shows a real-time progress card with step-by-step milestones, ETA, per-component status (NVIDIA, Intel GPU tools, Coral, AMD tools), boot sanity warnings, a rollback delta widget listing VMs / LXCs / components that exist on the host but weren't in the backup, and a log tail with an Issues-only filter. Past restores are archived and browsable.",
+ text: "Live post-restore progress — after a reboot the Backups tab shows a real-time progress card with step-by-step milestones, estimated time remaining, per-component status (NVIDIA, Intel GPU tools, Coral, AMD tools), boot sanity warnings, a rollback delta widget listing VMs / LXCs / components that exist on the host but weren't in the backup, and a log tail with an Issues-only filter. Past restores are archived and browsable.",
},
{
icon: ,
diff --git a/AppImage/components/restore-progress-card.tsx b/AppImage/components/restore-progress-card.tsx
index 42996057..b57c06c8 100644
--- a/AppImage/components/restore-progress-card.tsx
+++ b/AppImage/components/restore-progress-card.tsx
@@ -124,18 +124,21 @@ const formatRelative = (iso: string) => {
}
}
-// Rough ETA derived from steps_done + elapsed. Best-effort: skips at
-// step 0 (no data yet) and returns "—" once the run is terminal.
+// Rough time-remaining estimate derived from steps_done + elapsed.
+// Best-effort: at step 0 there's no data yet, so it returns
+// "estimating time…". After the run is terminal, "—". The output is
+// a full phrase so the caller doesn't have to add suffix words that
+// only make sense on some branches.
const computeEta = (state: RestoreState): string => {
if (state.status !== "running") return "—"
- if (!state.steps_done || state.steps_done <= 0) return "estimating…"
+ if (!state.steps_done || state.steps_done <= 0) return "estimating time…"
const elapsedSec = Math.max(1, Math.round((Date.now() - new Date(state.started_at).getTime()) / 1000))
const perStep = elapsedSec / state.steps_done
const remaining = Math.max(0, state.steps_total - state.steps_done)
const eta = Math.round(perStep * remaining)
- if (eta < 60) return `~${eta}s`
- if (eta < 3600) return `~${Math.round(eta / 60)}m`
- return `~${Math.round(eta / 3600)}h`
+ if (eta < 60) return `~${eta}s left`
+ if (eta < 3600) return `~${Math.round(eta / 60)}m left`
+ return `~${Math.round(eta / 3600)}h left`
}
// ── Small building blocks ─────────────────────────────────────
@@ -316,7 +319,7 @@ const RestoreDetailModal: React.FC<{
{state.current_step || "—"}
{state.steps_done}/{state.steps_total} steps
- {state.status === "running" && ` · ETA ${computeEta(state)}`}
+ {state.status === "running" && ` · ${computeEta(state)}`}
@@ -552,7 +555,7 @@ export const RestoreProgressCard: React.FC = () => {
{state.steps_done}/{state.steps_total} steps
- {state.status === "running" && ` · ETA ${computeEta(state)}`}
+ {state.status === "running" && ` · ${computeEta(state)}`}
{state.summary?.duration && state.status !== "running" && ` · ${state.summary.duration}`}
diff --git a/scripts/backup_restore/backup_host.sh b/scripts/backup_restore/backup_host.sh
index 0a6fc0e9..fa55494e 100755
--- a/scripts/backup_restore/backup_host.sh
+++ b/scripts/backup_restore/backup_host.sh
@@ -1752,7 +1752,7 @@ _rs_offer_reboot_after_pending() {
bg_block+=" • ${label} (${eta})"$'\n'
done
bg_block+=$'\n'"$(translate "Monitor progress:")"$'\n'
- bg_block+=" • $(translate "ProxMenux Monitor → Backups tab (live progress card with ETA, logs, rollback delta)")"$'\n'
+ bg_block+=" • $(translate "ProxMenux Monitor → Backups tab (live progress card with estimated time, logs, rollback delta)")"$'\n'
bg_block+=" • tail -f /var/log/proxmenux/proxmenux-cluster-postboot-*.log"$'\n'
bg_block+=" • systemctl status proxmenux-apply-cluster-postboot.service"$'\n\n'
bg_block+="$(translate "If notifications are enabled (Telegram/Discord/ntfy/...), you will receive a \"Host restore finished\" message when all background tasks complete.")"$'\n\n'
@@ -2683,7 +2683,7 @@ _rs_run_complete_guided() {
body+=$'\n'"${RS_HYDRATION_SUMMARY}"
fi
body+=$'\n'"\Zb\Z4$(translate "A reboot is required to finish the restore.")\Zn"$'\n\n'
- body+="$(translate "After the reboot you can follow the post-restore work live from ProxMenux Monitor → Backups tab (ETA, per-component status, log tail, rollback delta).")"$'\n\n'
+ body+="$(translate "After the reboot you can follow the post-restore work live from ProxMenux Monitor → Backups tab (estimated time, per-component status, log tail, rollback delta).")"$'\n\n'
body+="$(translate "If notifications are enabled (Telegram/Discord/ntfy/...), you will receive a \"Host restore finished\" message when all background tasks complete.")"$'\n\n'
body+="\Zb$(translate "Continue?")\ZB"