From 3ba507d841250d5d75162c1fe2aed8edfdd2f47c Mon Sep 17 00:00:00 2001 From: AlexCLeduc Date: Mon, 9 Dec 2024 10:25:49 -0500 Subject: [PATCH] fix: upgrade autocomplete (#399) --- server/cpho/forms.py | 68 +++++----------------------- server/cpho/views/user_management.py | 21 ++++----- server/requirements.txt | 2 +- server/server/settings.py | 2 + server/server/urls.py | 4 +- 5 files changed, 27 insertions(+), 70 deletions(-) diff --git a/server/cpho/forms.py b/server/cpho/forms.py index b01e16be..c85194e4 100644 --- a/server/cpho/forms.py +++ b/server/cpho/forms.py @@ -1,66 +1,22 @@ -from django.db.models import Q +from autocomplete import ModelAutocomplete, register -from autocomplete import HTMXAutoComplete -from autocomplete import widgets as ac_widgets +from cpho import constants +from cpho.models import Indicator, User -from cpho.models import Indicator, IndicatorDirectory, User - -class MultiIndicatorAutocomplete(HTMXAutoComplete): - name = "indicators" - multiselect = True +@register +class IndicatorAutocomplete(ModelAutocomplete): minimum_search_length = 0 model = Indicator - - def get_items(self, search=None, values=None): - data = Indicator.objects.all() - - if search is not None: - data = data.filter( - Q(name__icontains=search) - | Q(detailed_indicator__icontains=search) - | Q(sub_indicator_measurement__icontains=search) - ) - items = [{"label": str(x), "value": str(x.id)} for x in data] - return items - - if values is not None: - items = [ - {"label": str(x), "value": str(x.id)} - for x in data - if str(x.id) in values - ] - return items - - return [] + search_attrs = ["name", "detailed_indicator", "sub_indicator_measurement"] -class MultiUserAutocomplete(HTMXAutoComplete): - name = "users" - multiselect = True +@register +class UserAutocomplete(ModelAutocomplete): minimum_search_length = 0 model = User + search_attrs = ["username", "email", "name"] - def get_items(self, search=None, values=None): - data = User.objects.all() - - if search is not None: - filt = ( - Q(username__icontains=search) - | Q(email__icontains=search) - | Q(name__icontains=search) - ) - data = data.filter(filt) - - items = [{"label": str(x), "value": str(x.id)} for x in data] - return items - - if values is not None: - items = [ - {"label": str(x), "value": str(x.id)} - for x in data - if str(x.id) in values - ] - return items - - return [] + @classmethod + def get_queryset(cls): + return super().get_queryset().exclude(is_staff=True) diff --git a/server/cpho/views/user_management.py b/server/cpho/views/user_management.py index 14b840b1..541ff19c 100644 --- a/server/cpho/views/user_management.py +++ b/server/cpho/views/user_management.py @@ -14,14 +14,13 @@ View, ) -from autocomplete import HTMXAutoComplete -from autocomplete import widgets as ac_widgets +from autocomplete import AutocompleteWidget from phac_aspc.rules import test_rule from server.form_util import StandardFormMixin from cpho.constants import ADMIN_GROUP_NAME, HSO_GROUP_NAME -from cpho.forms import MultiIndicatorAutocomplete, MultiUserAutocomplete +from cpho.forms import IndicatorAutocomplete, UserAutocomplete from cpho.models import ( DimensionType, Indicator, @@ -213,10 +212,10 @@ class Meta: indicators = forms.ModelMultipleChoiceField( queryset=Indicator.objects.all(), required=False, - widget=ac_widgets.Autocomplete( - use_ac=MultiIndicatorAutocomplete, - attrs={ - "id": "indicators__textinput", + widget=AutocompleteWidget( + ac_class=IndicatorAutocomplete, + options={ + "multiselect": True, }, ), label=tdt("indicators"), @@ -225,10 +224,10 @@ class Meta: users = forms.ModelMultipleChoiceField( queryset=User.objects.all(), required=False, - widget=ac_widgets.Autocomplete( - use_ac=MultiUserAutocomplete, - attrs={ - "id": "users__textinput", + widget=AutocompleteWidget( + ac_class=UserAutocomplete, + options={ + "multiselect": True, }, ), label=tdt("users"), diff --git a/server/requirements.txt b/server/requirements.txt index 66600ebc..bb20c414 100644 --- a/server/requirements.txt +++ b/server/requirements.txt @@ -4,7 +4,7 @@ django-debug-toolbar==4.4.2 django-data-fetcher==2.2 django-graphiql-debug-toolbar==0.2.0 django-extensions==3.2.3 -django-htmx-autocomplete==0.8.2 +django-htmx-autocomplete==1.0.5 django-phac_aspc-helpers==3.1.1 Django==5.0.9 django-versionator==2.0.1 diff --git a/server/server/settings.py b/server/server/settings.py index d85d2e02..27a20de9 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -354,3 +354,5 @@ # CORS # for infobase and potentially anyone else who may want to use public data, CORS_ALLOW_ALL_ORIGINS = True + +AUTOCOMPLETE_BLOCK_UNAUTHENTICATED = True diff --git a/server/server/urls.py b/server/server/urls.py index 9449794b..03d22d6a 100644 --- a/server/server/urls.py +++ b/server/server/urls.py @@ -5,7 +5,7 @@ from django.urls import include, path, re_path from django.views.decorators.csrf import csrf_exempt -from autocomplete import HTMXAutoComplete +from autocomplete import urls as autocomplete_urls from server.middleware import allow_unauthenticated @@ -28,7 +28,7 @@ path("phac_admin/", admin.site.urls), path("login/", LoginView.as_view(), name="login"), path("logout/", LogoutView.as_view(), name="logout"), - *HTMXAutoComplete.url_dispatcher("ac"), + path("ac/", autocomplete_urls), path("", include(cpho_urls)), path( "graphiql/",