From 421fbed0990fb1b4c3b80ea571a60f6f4fafca96 Mon Sep 17 00:00:00 2001 From: Gareth Date: Tue, 23 Dec 2025 15:50:10 -0800 Subject: [PATCH] properly display item errors --- internal/protoutil/conversion.go | 12 ++- webui/messages/ar.json | 6 +- webui/messages/bn.json | 6 +- webui/messages/de.json | 6 +- webui/messages/en.json | 6 +- webui/messages/es.json | 6 +- webui/messages/fr.json | 6 +- webui/messages/hi.json | 6 +- webui/messages/id.json | 6 +- webui/messages/it.json | 6 +- webui/messages/pt.json | 6 +- webui/messages/ru.json | 6 +- webui/messages/zh.json | 6 +- webui/src/components/OperationRow.tsx | 124 +++++++++++++++++--------- 14 files changed, 151 insertions(+), 57 deletions(-) diff --git a/internal/protoutil/conversion.go b/internal/protoutil/conversion.go index ce0e70e6..1976ac36 100644 --- a/internal/protoutil/conversion.go +++ b/internal/protoutil/conversion.go @@ -95,9 +95,17 @@ func BackupProgressEntryToBackupError(b *restic.BackupProgressEntry) (*v1.Backup return nil, errors.New("BackupProgressEntry is not of type error") } + message := "" + if errMap, ok := b.Error.(map[string]interface{}); ok { + if msg, ok := errMap["message"].(string); ok { + message = msg + } + } + return &v1.BackupProgressError{ - Item: b.Item, - During: b.During, + Item: b.Item, + During: b.During, + Message: message, }, nil } diff --git a/webui/messages/ar.json b/webui/messages/ar.json index 502d812e..06ce0f4e 100644 --- a/webui/messages/ar.json +++ b/webui/messages/ar.json @@ -344,5 +344,9 @@ "op_row_removed_header": "تمت إزالة اللقطات", "op_row_removed_none": "لم يتم حذف أي لقطات.", "op_row_removed_id_col": "معرف اللقطة", - "op_row_removed_time_col": "وقت" + "op_row_removed_time_col": "وقت", + "op_row_restore_source": "مسار المصدر", + "op_row_restore_target": "مسار الوجهة", + "op_row_error_path": "طريق", + "op_row_error_message": "خطأ" } \ No newline at end of file diff --git a/webui/messages/bn.json b/webui/messages/bn.json index 86088d4f..536377b3 100644 --- a/webui/messages/bn.json +++ b/webui/messages/bn.json @@ -344,5 +344,9 @@ "op_row_removed_header": "স্ন্যাপশটগুলি সরানো হয়েছে", "op_row_removed_none": "কোনও স্ন্যাপশট সরানো হয়নি।", "op_row_removed_id_col": "স্ন্যাপশট আইডি", - "op_row_removed_time_col": "সময়" + "op_row_removed_time_col": "সময়", + "op_row_restore_source": "উৎস পথ", + "op_row_restore_target": "গন্তব্য পথ", + "op_row_error_path": "পথ", + "op_row_error_message": "ত্রুটি" } \ No newline at end of file diff --git a/webui/messages/de.json b/webui/messages/de.json index ceebb5da..e4905d0e 100644 --- a/webui/messages/de.json +++ b/webui/messages/de.json @@ -344,5 +344,9 @@ "op_row_removed_header": "Snapshots entfernt", "op_row_removed_none": "Es wurden keine Snapshots entfernt.", "op_row_removed_id_col": "Snapshot-ID", - "op_row_removed_time_col": "Zeit" + "op_row_removed_time_col": "Zeit", + "op_row_restore_source": "Quellpfad", + "op_row_restore_target": "Zielpfad", + "op_row_error_path": "Weg", + "op_row_error_message": "Fehler" } \ No newline at end of file diff --git a/webui/messages/en.json b/webui/messages/en.json index e3c72821..bc942c1b 100644 --- a/webui/messages/en.json +++ b/webui/messages/en.json @@ -344,5 +344,9 @@ "op_row_removed_header": "Removed snapshots", "op_row_removed_none": "No snapshots were removed.", "op_row_removed_id_col": "Snapshot ID", - "op_row_removed_time_col": "Time" + "op_row_removed_time_col": "Time", + "op_row_restore_source": "Source Path", + "op_row_restore_target": "Destination Path", + "op_row_error_path": "Path", + "op_row_error_message": "Error" } \ No newline at end of file diff --git a/webui/messages/es.json b/webui/messages/es.json index d2afb03a..3bc0f53f 100644 --- a/webui/messages/es.json +++ b/webui/messages/es.json @@ -344,5 +344,9 @@ "op_row_removed_header": "Instantáneas eliminadas", "op_row_removed_none": "No se eliminaron instantáneas.", "op_row_removed_id_col": "ID de instantánea", - "op_row_removed_time_col": "Tiempo" + "op_row_removed_time_col": "Tiempo", + "op_row_restore_source": "Ruta de origen", + "op_row_restore_target": "Ruta de destino", + "op_row_error_path": "Camino", + "op_row_error_message": "Error" } \ No newline at end of file diff --git a/webui/messages/fr.json b/webui/messages/fr.json index 496d9313..2636eef7 100644 --- a/webui/messages/fr.json +++ b/webui/messages/fr.json @@ -344,5 +344,9 @@ "op_row_removed_header": "Suppression des instantanés", "op_row_removed_none": "Aucune capture d'écran n'a été supprimée.", "op_row_removed_id_col": "ID de l'instantané", - "op_row_removed_time_col": "Temps" + "op_row_removed_time_col": "Temps", + "op_row_restore_source": "Chemin source", + "op_row_restore_target": "Chemin de destination", + "op_row_error_path": "Chemin", + "op_row_error_message": "Erreur" } diff --git a/webui/messages/hi.json b/webui/messages/hi.json index 24ed4957..36c5cec0 100644 --- a/webui/messages/hi.json +++ b/webui/messages/hi.json @@ -344,5 +344,9 @@ "op_row_removed_header": "स्नैपशॉट हटा दिए गए", "op_row_removed_none": "कोई भी स्नैपशॉट नहीं हटाया गया।", "op_row_removed_id_col": "स्नैपशॉट आईडी", - "op_row_removed_time_col": "समय" + "op_row_removed_time_col": "समय", + "op_row_restore_source": "स्रोत पथ", + "op_row_restore_target": "गंतव्य पथ", + "op_row_error_path": "पथ", + "op_row_error_message": "गलती" } \ No newline at end of file diff --git a/webui/messages/id.json b/webui/messages/id.json index 7a411989..e4a3b841 100644 --- a/webui/messages/id.json +++ b/webui/messages/id.json @@ -344,5 +344,9 @@ "op_row_removed_header": "Cuplikan layar dihapus", "op_row_removed_none": "Tidak ada foto yang dihapus.", "op_row_removed_id_col": "ID Cuplikan", - "op_row_removed_time_col": "Waktu" + "op_row_removed_time_col": "Waktu", + "op_row_restore_source": "Jalur Sumber", + "op_row_restore_target": "Jalur Tujuan", + "op_row_error_path": "Jalur", + "op_row_error_message": "Kesalahan" } \ No newline at end of file diff --git a/webui/messages/it.json b/webui/messages/it.json index 585acf9a..0a7dba7c 100644 --- a/webui/messages/it.json +++ b/webui/messages/it.json @@ -344,5 +344,9 @@ "op_row_removed_header": "Istantanee rimosse", "op_row_removed_none": "Nessuna istantanea è stata rimossa.", "op_row_removed_id_col": "ID istantanea", - "op_row_removed_time_col": "Tempo" + "op_row_removed_time_col": "Tempo", + "op_row_restore_source": "Percorso di origine", + "op_row_restore_target": "Percorso di destinazione", + "op_row_error_path": "Sentiero", + "op_row_error_message": "Errore" } diff --git a/webui/messages/pt.json b/webui/messages/pt.json index 5bc74ecb..c01f8705 100644 --- a/webui/messages/pt.json +++ b/webui/messages/pt.json @@ -344,5 +344,9 @@ "op_row_removed_header": "Capturas de tela removidas", "op_row_removed_none": "Nenhuma captura de tela foi removida.", "op_row_removed_id_col": "ID do instantâneo", - "op_row_removed_time_col": "Tempo" + "op_row_removed_time_col": "Tempo", + "op_row_restore_source": "Caminho de origem", + "op_row_restore_target": "Caminho de destino", + "op_row_error_path": "Caminho", + "op_row_error_message": "Erro" } \ No newline at end of file diff --git a/webui/messages/ru.json b/webui/messages/ru.json index 8b02d624..e08d9aee 100644 --- a/webui/messages/ru.json +++ b/webui/messages/ru.json @@ -344,5 +344,9 @@ "op_row_removed_header": "Удалены снимки экрана", "op_row_removed_none": "Никакие снимки не были удалены.", "op_row_removed_id_col": "Идентификатор снимка", - "op_row_removed_time_col": "Время" + "op_row_removed_time_col": "Время", + "op_row_restore_source": "Путь к источнику", + "op_row_restore_target": "Путь назначения", + "op_row_error_path": "Путь", + "op_row_error_message": "Ошибка" } \ No newline at end of file diff --git a/webui/messages/zh.json b/webui/messages/zh.json index 99288c98..066fe4d5 100644 --- a/webui/messages/zh.json +++ b/webui/messages/zh.json @@ -344,5 +344,9 @@ "op_row_removed_header": "已删除快照", "op_row_removed_none": "没有删除任何快照。", "op_row_removed_id_col": "快照 ID", - "op_row_removed_time_col": "时间" + "op_row_removed_time_col": "时间", + "op_row_restore_source": "源路径", + "op_row_restore_target": "目标路径", + "op_row_error_path": "小路", + "op_row_error_message": "错误" } diff --git a/webui/src/components/OperationRow.tsx b/webui/src/components/OperationRow.tsx index 036f9b2b..0cf01a77 100644 --- a/webui/src/components/OperationRow.tsx +++ b/webui/src/components/OperationRow.tsx @@ -210,11 +210,26 @@ export const OperationRow = ({ key: "errors", label: m.op_row_item_errors(), children: ( -
-            {backupOp.errors
-              .map((e) => m.op_row_error_on_item({ item: e.item }))
-              .join("\n")}
-          
+ + + + {m.op_row_error_path()} + {m.op_row_error_message()} + + + + {backupOp.errors.map((e, idx) => ( + + + {e.item} + + + {e.message || "Unknown error"} + + + ))} + + ), }); } @@ -476,19 +491,31 @@ const RestoreOperationStatus = ({ operation }: { operation: Operation }) => { return ( <> - {m.op_row_restore_desc({ - path: restoreOp.path, - target: restoreOp.target, - })} + + + {m.op_row_restore_source()} + + {restoreOp.path} + + + + {m.op_row_restore_target()} + + {restoreOp.target} + + + + {!isDone ? ( - + ) : null} + {operation.status == OperationStatus.STATUS_SUCCESS ? ( - <> + - + ) : null} -
- {m.op_row_restored_snapshot_id({ - id: normalizeSnapshotId(operation.snapshotId!), - })} - {lastStatus && ( - - - - {m.op_row_bytes_done_total()} - - - {formatBytes(Number(lastStatus.bytesRestored))}/ - {formatBytes(Number(lastStatus.totalBytes))} - - - - - {m.op_row_files_done_total()} - - - {Number(lastStatus.filesRestored)}/{Number(lastStatus.totalFiles)} - - - - )} + + + + {m.op_row_snapshot_id()} + + {normalizeSnapshotId(operation.snapshotId!)} + + + {lastStatus && ( + <> + + + {m.op_row_bytes_done_total()} + + + {formatBytes(Number(lastStatus.bytesRestored))}/ + {formatBytes(Number(lastStatus.totalBytes))} + + + + + {m.op_row_files_done_total()} + + + {Number(lastStatus.filesRestored)}/{Number(lastStatus.totalFiles)} + + + + )} + ); }; @@ -601,17 +633,17 @@ const BackupOperationStatus = ({ ? normalizeSnapshotId(sum.snapshotId!) : m.op_row_no_snapshot()} - + {m.op_row_files_added()} - {sum.filesNew.toString()} + {Number(sum.filesNew).toLocaleString()} {m.op_row_files_changed()} - {sum.filesChanged.toString()} + {Number(sum.filesChanged).toLocaleString()} @@ -619,11 +651,11 @@ const BackupOperationStatus = ({ {m.op_row_files_unmodified()} - {sum.filesUnmodified.toString()} + {Number(sum.filesUnmodified).toLocaleString()} - + {m.op_row_bytes_added()} @@ -636,6 +668,12 @@ const BackupOperationStatus = ({ {formatBytes(Number(sum.totalBytesProcessed))} + + {m.op_row_total_files()} + + {Number(sum.totalFilesProcessed).toLocaleString()} + + );