diff --git a/dist/backupper-2026.06.14-x86_64-1.txz.sha256 b/dist/backupper-2026.06.14-x86_64-1.txz.sha256 deleted file mode 100644 index e18331d..0000000 --- a/dist/backupper-2026.06.14-x86_64-1.txz.sha256 +++ /dev/null @@ -1 +0,0 @@ -7f2bb1ba2b35b4c507680885a1284769fe4261c74d58c611c79d5eb10bf6782c backupper-2026.06.14-x86_64-1.txz diff --git a/dist/backupper-2026.06.14-x86_64-1.txz b/dist/backupper-2026.06.14.1-x86_64-1.txz similarity index 55% rename from dist/backupper-2026.06.14-x86_64-1.txz rename to dist/backupper-2026.06.14.1-x86_64-1.txz index b022684..60d1d8e 100644 Binary files a/dist/backupper-2026.06.14-x86_64-1.txz and b/dist/backupper-2026.06.14.1-x86_64-1.txz differ diff --git a/dist/backupper-2026.06.14.1-x86_64-1.txz.sha256 b/dist/backupper-2026.06.14.1-x86_64-1.txz.sha256 new file mode 100644 index 0000000..566d67c --- /dev/null +++ b/dist/backupper-2026.06.14.1-x86_64-1.txz.sha256 @@ -0,0 +1 @@ +29655e71df818c71341058d031570f204d423eea63de4e199190c44b217343cc backupper-2026.06.14.1-x86_64-1.txz diff --git a/dist/backupper.plg b/dist/backupper.plg index bd0a213..bd06b3d 100644 --- a/dist/backupper.plg +++ b/dist/backupper.plg @@ -2,13 +2,16 @@ - + - + ]> +### 2026.06.14.1 +- Match the backup source browser layout and controls to the snapshot file browser. + ### 2026.06.14 - Switch to lexicographically sortable date versions for reliable Unraid update detection. - Add checkbox folder browsers for backup sources and persistent multi-selection for restores. diff --git a/plugin/backupper.plg b/plugin/backupper.plg index 2d6a7bc..03c02d2 100644 --- a/plugin/backupper.plg +++ b/plugin/backupper.plg @@ -2,13 +2,16 @@ - + ]> +### 2026.06.14.1 +- Match the backup source browser layout and controls to the snapshot file browser. + ### 2026.06.14 - Switch to lexicographically sortable date versions for reliable Unraid update detection. - Add checkbox folder browsers for backup sources and persistent multi-selection for restores. diff --git a/webgui/Backupper.page b/webgui/Backupper.page index b03a096..f4b9a22 100644 --- a/webgui/Backupper.page +++ b/webgui/Backupper.page @@ -9,10 +9,10 @@ Tag="backup restic snapshots restore" - +
-

Backupper 2026.06.14

Encrypted Restic backups for Unraid

+

Backupper 2026.06.14.1

Encrypted Restic backups for Unraid

Connecting...
- + diff --git a/webgui/assets/backupper.css b/webgui/assets/backupper.css index 6a1f891..4d51f25 100644 --- a/webgui/assets/backupper.css +++ b/webgui/assets/backupper.css @@ -63,11 +63,12 @@ .bu-table-actions { align-items: flex-start; min-width: 310px; } .bu-table-actions .bu-button { flex: 0 0 auto; } .bu-warning { color: var(--bu-bad) !important; display: block; font-size: 13px; font-weight: 700; margin-top: 5px; } -.bu-browser { border: 1px solid var(--bu-border); border-radius: 6px; margin-top: 10px; max-height: 430px; overflow: auto; padding: 12px; } -.bu-browser-head { align-items: center; display: flex; gap: 10px; justify-content: space-between; margin-bottom: 10px; } +.bu-browser-card { border: 1px solid var(--bu-border); border-radius: 6px; margin-top: 10px; padding: 14px; } +.bu-browser-scroll { max-height: 430px; overflow: auto; } .bu-selection-list { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; } .bu-selection { background: var(--bu-panel-alt); border: 1px solid var(--bu-border); border-radius: 999px; color: var(--bu-text); font-size: 12px; padding: 4px 8px; } -.bu-browser input[type="checkbox"], .bu-table input[type="checkbox"] { accent-color: var(--bu-accent); height: 20px; width: 20px; } +.bu-browser-card input[type="checkbox"], .bu-table input[type="checkbox"] { accent-color: var(--bu-accent); height: 20px; width: 20px; } +.bu-count { align-items: center; border: 1px solid var(--bu-border); border-radius: 999px; display: inline-flex; font-size: 13px; font-weight: 700; padding: 7px 11px; } #backupper-app .bu-button { appearance: none; diff --git a/webgui/assets/backupper.js b/webgui/assets/backupper.js index 25c348c..9ad1954 100644 --- a/webgui/assets/backupper.js +++ b/webgui/assets/backupper.js @@ -60,6 +60,7 @@ 'cancel-form': 'Verwirft ungespeicherte Eingaben und kehrt zur Übersicht zurück.', 'browser-up': 'Öffnet im Snapshot-Browser das übergeordnete Verzeichnis.', 'source-up': 'Öffnet im Ordner-Browser das übergeordnete Verzeichnis.', + 'select-current-source': 'Wählt den aktuell geöffneten Ordner vollständig als Backup-Quelle aus.', 'select-current-restore': 'Wählt den aktuell geöffneten Snapshot-Ordner vollständig für die Wiederherstellung aus.', }; @@ -226,7 +227,7 @@ -

Backup folders

Select one or more folders. Open navigates into a folder without selecting it.
+

Backup folders

Select folders exactly like files and folders in the snapshot browser.
@@ -240,9 +241,9 @@ const host = document.getElementById('bu-source-browser'); if (!host) return; const selected = new Set(state.backupSelections); - const rows = state.sourceDirectories.map(item => `${esc(item.name)}
${esc(item.path)}${button('Open',`open-source-dir:${encodeURIComponent(item.path)}`)}`).join(''); + const rows = state.sourceDirectories.map(item => `dir${esc(item.name)}${esc(item.path)}${button('Open',`open-source-dir:${encodeURIComponent(item.path)}`)}`).join(''); const chosen = state.backupSelections.length ? state.backupSelections.map(path=>`${esc(path)}`).join('') : 'No folders selected.'; - host.innerHTML = `
Folder: ${esc(state.sourceBrowserPath)}
${state.sourceBrowserPath!=='/'?button('Up','source-up'):''}
${chosen}
${rows||''}
SelectFolder
No subfolders found.
`; + host.innerHTML = `

Backup source browser

${esc(state.sourceBrowserPath)}
${state.sourceBrowserPath!=='/'?button('Select current folder','select-current-source'):''}${state.sourceBrowserPath!=='/'?button('Up','source-up'):''}Selected: ${state.backupSelections.length}
${chosen}
${rows||''}
SelectTypeNamePath
No subfolders found.
`; enhanceTooltips(host); } @@ -335,6 +336,7 @@ if (name === 'browse') { state.selectedSnapshot=a; state.browserPath='/'; state.restoreIncludes=[]; state.files=await api(`/v1/repositories/${state.snapshotRepo}/snapshots/${a}/files?path=${encodeURIComponent('/')}`); return render(); } if (name === 'open-source-dir') { return loadSourceDirectories(decodeURIComponent(a)); } if (name === 'source-up') { const parent=state.sourceBrowserPath==='/'?'/':state.sourceBrowserPath.split('/').slice(0,-1).join('/')||'/'; return loadSourceDirectories(parent==='/mnt'?'/':parent); } + if (name === 'select-current-source') { if(!state.backupSelections.includes(state.sourceBrowserPath)) state.backupSelections.push(state.sourceBrowserPath); return renderSourceBrowser(); } if (name === 'open-dir') { state.browserPath=decodeURIComponent(a); state.files=await api(`/v1/repositories/${state.snapshotRepo}/snapshots/${state.selectedSnapshot}/files?path=${encodeURIComponent(state.browserPath)}`); return render(); } if (name === 'browser-up') { state.browserPath=state.browserPath.replace(/\/$/,'').split('/').slice(0,-1).join('/')||'/'; state.files=await api(`/v1/repositories/${state.snapshotRepo}/snapshots/${state.selectedSnapshot}/files?path=${encodeURIComponent(state.browserPath)}`); return render(); } if (name === 'select-current-restore') { if(!state.restoreIncludes.includes(state.browserPath)) state.restoreIncludes.push(state.browserPath); return render(); }