From fba8d5ab051aef100ede8c21a29e9dc87152843c Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 27 Oct 2025 14:43:41 +0000 Subject: [PATCH] Add supervisor search functionality with HTMX support for manual selection in bulk updates --- .../partials/supervisor_search_results.html | 12 +++++ .../generic/trainees_bulk_update.html | 47 +++++++++++++++---- generic/urls.py | 1 + generic/views.py | 20 ++++++++ 4 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 generic/templates/generic/partials/supervisor_search_results.html diff --git a/generic/templates/generic/partials/supervisor_search_results.html b/generic/templates/generic/partials/supervisor_search_results.html new file mode 100644 index 00000000..7896bb21 --- /dev/null +++ b/generic/templates/generic/partials/supervisor_search_results.html @@ -0,0 +1,12 @@ +{% if results %} + +{% else %} +
No supervisors found
+{% endif %} diff --git a/generic/templates/generic/trainees_bulk_update.html b/generic/templates/generic/trainees_bulk_update.html index ee845a45..28de2c95 100644 --- a/generic/templates/generic/trainees_bulk_update.html +++ b/generic/templates/generic/trainees_bulk_update.html @@ -40,19 +40,37 @@
No match
-
- - - -
+
+
+ + + +
+
+
+
-
- -
{% endif %} {{ r.supervisor_text }} - {% if r.matched_supervisor %}{{ r.matched_supervisor.name }}{% else %}No match{% endif %} + + {% if r.matched_supervisor %} + {{ r.matched_supervisor.name }} + {% else %} +
+ No match +
+
+ + + +
+
+
+ +
+ {% endif %} + {% endfor %} @@ -80,6 +98,17 @@ } } + function setManualSupervisor(rowIndex, id, text) { + const hiddenInput = document.getElementById('manual_supervisor_' + rowIndex); + const resultsDiv = document.getElementById('supervisor-results-' + rowIndex); + if (hiddenInput) { + hiddenInput.value = id; + } + if (resultsDiv) { + resultsDiv.innerHTML = '
Selected: ' + escapeHtml(text) + '
'; + } + } + function escapeHtml(unsafe) { if (!unsafe) return ''; return String(unsafe) diff --git a/generic/urls.py b/generic/urls.py index 6d4fb9cc..af3aa893 100755 --- a/generic/urls.py +++ b/generic/urls.py @@ -58,6 +58,7 @@ urlpatterns = [ name="supervisor-autocomplete", ), path("user-search/", views.user_search, name="user_search"), + path("supervisor-search/", views.supervisor_search, name="supervisor_search"), path( "cids/manage//update", views.CidUserUpdate.as_view(), name="update_cid" ), diff --git a/generic/views.py b/generic/views.py index 4efa8cc3..df5daf36 100644 --- a/generic/views.py +++ b/generic/views.py @@ -4423,6 +4423,26 @@ def user_search(request): return JsonResponse({"results": results}) +@user_is_cid_user_manager +def supervisor_search(request): + """Simple JSON/HTMX endpoint to search supervisors by name/email for manual matching.""" + q = request.GET.get("q", "").strip() + results = [] + if q: + qs = Supervisor.objects.filter( + Q(name__icontains=q) | Q(email__icontains=q) + ).order_by("name")[:50] + + for s in qs: + results.append({"id": s.pk, "text": f"{s.name} ({s.email})"}) + + row = request.GET.get("row") + if request.headers.get("HX-Request") == "true" or row is not None: + return render(request, "generic/partials/supervisor_search_results.html", {"results": results, "row": int(row) if row is not None else None}) + + return JsonResponse({"results": results}) + + def create_trainee(request, context=None): return create_user(request, context, trainee=True)