From a5d24e6db59fee3ad6560ab1eb927f9a6078f1ac Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Tue, 10 May 2022 16:41:46 +0200 Subject: [PATCH] WIP: JS Tree improvements * adds optional short_name rendering for selectable codes * refactors autocomplete field for compensation state into custom js tree widget * adds single select (radio) alternative to tree widget templates --- codelist/models.py | 9 ++- compensation/forms/modalForms.py | 19 ++--- intervention/inputs.py | 67 +++++++++++++++++- .../checkbox-tree-select-content.html | 5 +- .../checkbox}/checkbox-tree-select.html | 2 +- .../tree/radio/radio-tree-select-content.html | 25 +++++++ .../widgets/tree/radio/radio-tree-select.html | 70 +++++++++++++++++++ 7 files changed, 173 insertions(+), 24 deletions(-) rename konova/templates/konova/widgets/{ => tree/checkbox}/checkbox-tree-select-content.html (84%) rename konova/templates/konova/widgets/{ => tree/checkbox}/checkbox-tree-select.html (96%) create mode 100644 konova/templates/konova/widgets/tree/radio/radio-tree-select-content.html create mode 100644 konova/templates/konova/widgets/tree/radio/radio-tree-select.html diff --git a/codelist/models.py b/codelist/models.py index de7a210..8e5de0c 100644 --- a/codelist/models.py +++ b/codelist/models.py @@ -65,24 +65,23 @@ class KonovaCode(models.Model): ret_val += ", " + self.parent.long_name return ret_val - def add_children(self): + def add_children(self, order_by: str = "long_name"): """ Adds all children (resurcively until leaf) as .children to the KonovaCode Returns: code (KonovaCode): The manipulated KonovaCode instance """ if self.is_leaf: - return None + return self children = KonovaCode.objects.filter( - code_lists__in=self.code_lists.all(), parent=self ).order_by( - "long_name" + order_by ) self.children = children for child in children: - child.add_children() + child.add_children(order_by) return self diff --git a/compensation/forms/modalForms.py b/compensation/forms/modalForms.py index 8404c7a..d129459 100644 --- a/compensation/forms/modalForms.py +++ b/compensation/forms/modalForms.py @@ -17,7 +17,8 @@ from codelist.models import KonovaCode from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID, \ CODELIST_COMPENSATION_ACTION_DETAIL_ID from compensation.models import CompensationDocument, EcoAccountDocument -from intervention.inputs import CompensationActionTreeCheckboxSelectMultiple +from intervention.inputs import CompensationActionTreeCheckboxSelectMultiple, \ + CompensationStateTreeRadioSelect from konova.contexts import BaseContext from konova.forms import BaseModalForm, NewDocumentModalForm, RemoveModalForm from konova.models import DeadlineType @@ -156,22 +157,12 @@ class NewStateModalForm(BaseModalForm): What has been on this area before changes/compensations have been applied and what will be the result ('after')? """ - biotope_type = forms.ModelChoiceField( + biotope_type = forms.MultipleChoiceField( label=_("Biotope Type"), label_suffix="", required=True, help_text=_("Select the biotope type"), - queryset=KonovaCode.objects.filter( - is_archived=False, - is_leaf=True, - code_lists__in=[CODELIST_BIOTOPES_ID], - ), - widget=autocomplete.ModelSelect2( - url="codes-biotope-autocomplete", - attrs={ - "data-placeholder": _("Biotope Type"), - } - ), + widget=CompensationStateTreeRadioSelect(), ) biotope_extra = forms.ModelMultipleChoiceField( label=_("Biotope additional type"), @@ -272,7 +263,7 @@ class EditCompensationStateModalForm(NewStateModalForm): super().__init__(*args, **kwargs) self.form_title = _("Edit state") form_data = { - "biotope_type": self.state.biotope_type, + "biotope_type": self.state.biotope_type.id, "biotope_extra": self.state.biotope_type_details.all(), "surface": self.state.surface, } diff --git a/intervention/inputs.py b/intervention/inputs.py index 34fe043..a08c0b7 100644 --- a/intervention/inputs.py +++ b/intervention/inputs.py @@ -1,6 +1,6 @@ from django import forms from codelist.models import KonovaCode -from codelist.settings import CODELIST_COMPENSATION_ACTION_ID +from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID class DummyFilterInput(forms.HiddenInput): @@ -38,7 +38,17 @@ class TreeCheckboxSelectMultiple(forms.CheckboxSelectMultiple): """ Provides multiple selection of parent-child data """ - template_name = "konova/widgets/checkbox-tree-select.html" + template_name = "konova/widgets/tree/checkbox/checkbox-tree-select.html" + + class meta: + abstract = True + + +class TreeRadioSelect(forms.RadioSelect): + """ Provides single selection of parent-child data + + """ + template_name = "konova/widgets/tree/radio/radio-tree-select.html" class meta: abstract = True @@ -68,6 +78,30 @@ class KonovaCodeTreeCheckboxSelectMultiple(TreeCheckboxSelectMultiple): return context +class KonovaCodeTreeRadioSelect(TreeRadioSelect): + """ Provides single selection of KonovaCode + + """ + filter = None + + def __init__(self, *args, **kwargs): + self.code_list = kwargs.pop("code_list", None) + self.filter = kwargs.pop("filter", {}) + super().__init__(*args, **kwargs) + + def get_context(self, name, value, attrs): + context = super().get_context(name, value, attrs) + codes = KonovaCode.objects.filter( + **self.filter, + ) + codes = [ + parent_code.add_children() + for parent_code in codes + ] + context["codes"] = codes + return context + + class CompensationActionTreeCheckboxSelectMultiple(KonovaCodeTreeCheckboxSelectMultiple): """ Provides multiple selection of CompensationActions @@ -79,4 +113,31 @@ class CompensationActionTreeCheckboxSelectMultiple(KonovaCodeTreeCheckboxSelectM self.filter = { "code_lists__in": [CODELIST_COMPENSATION_ACTION_ID], "parent": None, - } \ No newline at end of file + } + + +class CompensationStateTreeRadioSelect(KonovaCodeTreeRadioSelect): + """ Provides single selection of CompensationState + + """ + filter = None + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.filter = { + "code_lists__in": [CODELIST_BIOTOPES_ID], + "parent": None, + "is_archived": False, + } + + def get_context(self, name, value, attrs): + context = super().get_context(name, value, attrs) + codes = KonovaCode.objects.filter( + **self.filter, + ) + codes = [ + parent_code.add_children("short_name") + for parent_code in codes + ] + context["codes"] = codes + return context \ No newline at end of file diff --git a/konova/templates/konova/widgets/checkbox-tree-select-content.html b/konova/templates/konova/widgets/tree/checkbox/checkbox-tree-select-content.html similarity index 84% rename from konova/templates/konova/widgets/checkbox-tree-select-content.html rename to konova/templates/konova/widgets/tree/checkbox/checkbox-tree-select-content.html index 31599ef..84f97ec 100644 --- a/konova/templates/konova/widgets/checkbox-tree-select-content.html +++ b/konova/templates/konova/widgets/tree/checkbox/checkbox-tree-select-content.html @@ -10,12 +10,15 @@ {% fa5_icon 'angle-down' %} {% endif %} + {% if code.short_name %} + ({{code.short_name}}) + {% endif %} {{code.long_name}} {% if not code.is_leaf %}
{% with code.children as codes %} - {% include 'konova/widgets/checkbox-tree-select-content.html' %} + {% include 'konova/widgets/tree/checkbox/checkbox-tree-select-content.html' %} {% endwith %}
{% endif %} diff --git a/konova/templates/konova/widgets/checkbox-tree-select.html b/konova/templates/konova/widgets/tree/checkbox/checkbox-tree-select.html similarity index 96% rename from konova/templates/konova/widgets/checkbox-tree-select.html rename to konova/templates/konova/widgets/tree/checkbox/checkbox-tree-select.html index 68e4321..9626945 100644 --- a/konova/templates/konova/widgets/checkbox-tree-select.html +++ b/konova/templates/konova/widgets/tree/checkbox/checkbox-tree-select.html @@ -5,7 +5,7 @@
- {% include 'konova/widgets/checkbox-tree-select-content.html' %} + {% include 'konova/widgets/tree/checkbox/checkbox-tree-select-content.html' %}
\ No newline at end of file