diff --git a/web/static/js/app.js b/web/static/js/app.js index 985009e8..bb0dcf62 100644 --- a/web/static/js/app.js +++ b/web/static/js/app.js @@ -90,3 +90,20 @@ function toggleEditMode(index) { } lucide.createIcons(); } + +// Format a byte count like core.system_utils.format_bytes (1024-based, 2 decimals, +// e.g. "42.93 GB"), so sizes computed in the browser match the ones the server renders. +// settings/cache.html declares its own GB/TB-only formatBytes() before this file loads; +// leave that one alone so its output does not change. +if (typeof window.formatBytes !== 'function') { + window.formatBytes = function formatBytes(bytes) { + var size = Number(bytes) || 0; + var units = ['B', 'KB', 'MB', 'GB', 'TB']; + var i = 0; + while (size >= 1024 && i < units.length - 1) { + size /= 1024; + i++; + } + return i === 0 ? Math.round(size) + ' B' : size.toFixed(2) + ' ' + units[i]; + }; +} diff --git a/web/templates/maintenance/index.html b/web/templates/maintenance/index.html index 2c4eabd2..38d5261f 100644 --- a/web/templates/maintenance/index.html +++ b/web/templates/maintenance/index.html @@ -119,6 +119,34 @@

Confirm Action

formData.append('paths_json', JSON.stringify(Array.from(paths))); } +// Total size of the checked boxes matching `selector`. Every checkbox is one file, so the +// size comes from its own row. A group row's data-size is the whole group (primary + children, +// used for sorting), so group rows expose their own file in data-file-size to avoid +// counting the children twice when the group checkbox selects them too. +function sumCheckedSize(selector) { + let total = 0; + document.querySelectorAll(selector + ':checked').forEach(cb => { + const row = cb.closest('tr'); + if (!row) return; + const size = parseInt(row.dataset.fileSize || row.dataset.size, 10); + if (size > 0) total += size; + }); + return total; +} + +// Write " · 42.93 GB" next to a "Selected: N" counter (empty when no size is known). +function setSelectedSize(spanId, bytes) { + const span = document.getElementById(spanId); + if (!span) return; + // The size is only a hint: if formatting ever fails (e.g. a cached app.js from before + // formatBytes() moved there), show nothing instead of breaking the selection itself. + try { + span.textContent = bytes > 0 ? ' \u00b7 ' + formatBytes(bytes) : ''; + } catch (e) { + span.textContent = ''; + } +} + // Selected items tracking let selectedUntrackedFiles = new Set(); let selectedOrphanedBackups = new Set(); @@ -155,6 +183,7 @@

Confirm Action

if (count > 0) { bulkActions.style.display = 'flex'; countSpan.textContent = count; + setSelectedSize('untracked-selected-size', sumCheckedSize('.untracked-checkbox')); } else { bulkActions.style.display = 'none'; } @@ -193,6 +222,7 @@

Confirm Action

if (count > 0) { bulkActions.style.display = 'flex'; countSpan.textContent = count; + setSelectedSize('orphaned-selected-size', sumCheckedSize('.orphaned-checkbox')); // Only show restore button if at least one orphaned (not redundant) backup is selected if (restoreBtn) { @@ -675,6 +705,7 @@

if (count > 0) { bulkActions.style.display = 'flex'; if (countSpan) countSpan.textContent = count; + setSelectedSize('dup-selected-size', sumCheckedSize('.dup-file-checkbox')); } else { bulkActions.style.display = 'none'; } diff --git a/web/templates/maintenance/partials/audit_results.html b/web/templates/maintenance/partials/audit_results.html index c04d01fa..e85b652b 100644 --- a/web/templates/maintenance/partials/audit_results.html +++ b/web/templates/maintenance/partials/audit_results.html @@ -118,8 +118,8 @@

Untracked Files ({{ results.untracked_files|length }}{% if results.grouped_u These files are on cache but not managed by PlexCache. {% if is_unraid %}The Unraid mover will handle them normally.{% else %}They will not be automatically moved.{% endif %} Use the actions below to decide what happens to them:

-
@@ -155,7 +157,7 @@

Untracked Files ({{ results.untracked_files|length }}{% if results.grouped_u {% set file = group.primary %} {% set children = group.children %} {% set group_size = file.size + children|sum(attribute='size') if children else file.size %} - + @@ -256,15 +258,17 @@

Backup Cleanup ({{ results.orphaned_plexcached|length }})

{% endif %}

-
-