diff --git a/atlas/templates/atlas/new_uploads.html b/atlas/templates/atlas/new_uploads.html index 2d0dec84..671dffd5 100644 --- a/atlas/templates/atlas/new_uploads.html +++ b/atlas/templates/atlas/new_uploads.html @@ -67,7 +67,12 @@
- +Potential anonymisation issues were detected. Flagged series are highlighted below.
@@ -431,6 +436,7 @@ function updateUploadButtonState() { const uploadButton = document.getElementById("uploadButton"); const anonAlert = document.querySelector(".anon-alert"); + const deselectDuplicatesBtn = document.getElementById("deselect-duplicates"); const hasSelected = window.uploadPreview.records.some(r => r.include); const hasWarnings = hasAnonymisationWarnings(); const hasDuplicates = window.uploadPreview.records.some(r => r.include && r.duplicate); @@ -439,6 +445,9 @@ window.uploadPreview.records.some((r) => r.include && !r.duplicateChecked); renderAnonymisationIssueSummary(); + if (deselectDuplicatesBtn) { + deselectDuplicatesBtn.classList.toggle("d-none", !hasDuplicates); + } if (!hasSelected) { uploadButton.disabled = true; @@ -483,14 +492,36 @@ } function getSeriesStatusClass(series) { + const includeCount = series.files.filter(f => f.include).length; + if (!includeCount) return "series-card excluded"; + const hasTagWarnings = series.files.some(f => f.tagWarnings.length > 0); const hasOcrWarnings = series.files.some(f => f.ocrWarning); - const hasDuplicates = series.files.some(f => f.duplicate); + const hasDuplicates = series.files.some(f => f.include && f.duplicate); if (hasTagWarnings || hasOcrWarnings) return "series-card warning"; if (hasDuplicates) return "series-card duplicate"; return "series-card"; } + function deselectDuplicateSeries() { + const duplicateSeriesUids = new Set( + window.uploadPreview.records + .filter((record) => record.include && record.duplicate) + .map((record) => record.seriesUid) + ); + + if (!duplicateSeriesUids.size) { + toastr.info("No selected duplicate series to deselect."); + return; + } + + duplicateSeriesUids.forEach((seriesUid) => applyIncludeToSeries(seriesUid, false)); + window.uploadPreview.forceAnonymisationOverride = false; + scheduleDuplicateCheck(); + renderGroupedPreview(); + toastr.info(`Deselected ${duplicateSeriesUids.size} duplicate series.`); + } + function renderGroupedPreview() { const groupedRoot = document.getElementById("preupload-grouped"); const grouped = window.uploadPreview.grouped; @@ -1264,6 +1295,10 @@ renderGroupedPreview(); }); + bindIfExists("deselect-duplicates", "click", () => { + deselectDuplicateSeries(); + }); + bindIfExists("show-thumbnails", "change", () => { renderGroupedPreview(); }); @@ -1339,6 +1374,13 @@ background: rgba(220, 53, 69, 0.08); } + .series-card.excluded { + border-color: rgba(148, 163, 184, 0.35); + background: rgba(148, 163, 184, 0.08); + opacity: 0.55; + filter: grayscale(0.25); + } + .series-header { display: flex; justify-content: space-between;