diff --git a/atlas/templates/atlas/partials/truncate_result.html b/atlas/templates/atlas/partials/truncate_result.html
new file mode 100644
index 00000000..2b774c49
--- /dev/null
+++ b/atlas/templates/atlas/partials/truncate_result.html
@@ -0,0 +1,10 @@
+
+
Truncate complete.
+
Removed {{ images_removed|length }} images from series {{ series.pk }}.
+
+{% if images_removed %}
+
+ Show removed image IDs
+ {{ images_removed|join:", " }}
+
+{% endif %}
diff --git a/atlas/templates/atlas/series_viewer.html b/atlas/templates/atlas/series_viewer.html
index 7a0d2c3e..92f071f5 100755
--- a/atlas/templates/atlas/series_viewer.html
+++ b/atlas/templates/atlas/series_viewer.html
@@ -251,8 +251,10 @@
return;
}
- if(confirm(`Trucated series. This will leave ${upper_bound - lower_bound + 1} images.`) == true) {
- htmx.ajax("GET", `{% url 'api-1:series_truncate' series.id '****' '++++' %}`.replace("****", lower_bound).replace("++++", upper_bound), "#truncate-output")
+ if(confirm(`Trucated series. This will leave ${upper_bound - lower_bound + 1} images.`) == true) {
+ const truncateTemplate = `{% url 'atlas:series_truncate' series.id 0 0 %}`; // e.g. /atlas/series/920/truncate/0/0/
+ const truncateUrl = truncateTemplate.replace('/0/0/', `/${lower_bound}/${upper_bound}/`);
+ htmx.ajax("GET", truncateUrl, "#truncate-output")
}
diff --git a/atlas/urls.py b/atlas/urls.py
index 71142d2e..0ed24f9e 100755
--- a/atlas/urls.py
+++ b/atlas/urls.py
@@ -472,6 +472,11 @@ urlpatterns = [
# TODO: case context series viewing (so that we can view series in the context of a case)
path("series/", views.series_detail, name="series_detail"),
path("series//viewer", views.series_viewer, name="series_viewer"),
+ path(
+ "series//truncate///",
+ views.series_truncate_htmx,
+ name="series_truncate",
+ ),
path("series//images/", views.series_images_partial, name="series_images"),
path("series//authors", views.SeriesAuthorUpdate.as_view(), name="series_authors"),
path("series//finding/related", views.series_finding_related, name="series_finding_related"),
diff --git a/atlas/views.py b/atlas/views.py
index c614efd1..02129413 100755
--- a/atlas/views.py
+++ b/atlas/views.py
@@ -196,6 +196,43 @@ from helpers.cimar import CimarAPI
logger = logging.getLogger(__name__)
+@login_required
+def series_truncate_htmx(request, series_id, start, end):
+ """HTMX endpoint to truncate a series' images to the given inclusive
+ start/end bounds (zero-based). Returns an HTML fragment with the result.
+ """
+ series = get_object_or_404(Series, pk=series_id)
+
+ if not series.check_user_can_edit(request.user):
+ return HttpResponse("Permission denied
")
+
+ images_removed = []
+ for n, image in enumerate(series.get_images()):
+ if n >= int(start) and n <= int(end):
+ # keep images within bounds
+ continue
+ else:
+ image.removed = True
+ image.image = None
+ image.save()
+ images_removed.append(image.pk)
+
+ # Recalculate stored series size
+ try:
+ series.get_total_image_size(refresh=True)
+ except Exception:
+ # ignore errors when recalculating
+ pass
+
+ # Render a simple message fragment for HTMX swap
+ html = render_to_string(
+ "atlas/partials/truncate_result.html",
+ {"images_removed": images_removed, "series": series},
+ request=request,
+ )
+ return HttpResponse(html)
+
+
@login_required
def case_search_partial(request):
"""Return an HTMX partial listing cases matching the query parameter `q`.