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..581a7b3 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.ChoiceField( 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"), @@ -209,6 +200,16 @@ class NewStateModalForm(BaseModalForm): super().__init__(*args, **kwargs) self.form_title = _("New state") self.form_caption = _("Insert data for the new state") + choices = KonovaCode.objects.filter( + code_lists__in=[CODELIST_BIOTOPES_ID], + is_archived=False, + is_leaf=True, + ).values_list("id", flat=True) + choices = [ + (choice, choice) + for choice in choices + ] + self.fields["biotope_type"].choices = choices def save(self, is_before_state: bool = False): state = self.instance.add_state(self, is_before_state) @@ -271,8 +272,9 @@ class EditCompensationStateModalForm(NewStateModalForm): self.state = kwargs.pop("state", None) super().__init__(*args, **kwargs) self.form_title = _("Edit state") + biotope_type_id = self.state.biotope_type.id if self.state.biotope_type else None form_data = { - "biotope_type": self.state.biotope_type, + "biotope_type": biotope_type_id, "biotope_extra": self.state.biotope_type_details.all(), "surface": self.state.surface, } @@ -280,7 +282,8 @@ class EditCompensationStateModalForm(NewStateModalForm): def save(self, is_before_state: bool = False): state = self.state - state.biotope_type = self.cleaned_data.get("biotope_type", None) + biotope_type_id = self.cleaned_data.get("biotope_type", None) + state.biotope_type = KonovaCode.objects.get(id=biotope_type_id) state.biotope_type_details.set(self.cleaned_data.get("biotope_extra", [])) state.surface = self.cleaned_data.get("surface", None) state.save() diff --git a/compensation/models/compensation.py b/compensation/models/compensation.py index 3deff50..3727e0c 100644 --- a/compensation/models/compensation.py +++ b/compensation/models/compensation.py @@ -8,6 +8,8 @@ Created on: 16.11.21 import shutil from django.contrib import messages + +from codelist.models import KonovaCode from user.models import User, Team from django.db import models, transaction from django.db.models import QuerySet, Sum @@ -142,8 +144,10 @@ class AbstractCompensation(BaseObject, GeoReferencedMixin): """ form_data = form.cleaned_data with transaction.atomic(): + biotope_type_id = form_data["biotope_type"] + code = KonovaCode.objects.get(id=biotope_type_id) state = CompensationState.objects.create( - biotope_type=form_data["biotope_type"], + biotope_type=code, surface=form_data["surface"], ) state_additional_types = form_data["biotope_extra"] 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/static/css/konova.css b/konova/static/css/konova.css index 7e7f3fd..ed79704 100644 --- a/konova/static/css/konova.css +++ b/konova/static/css/konova.css @@ -262,4 +262,13 @@ Similar to bootstraps 'shadow-lg' padding-left: 2em; } - */ \ No newline at end of file + */ +.collapse-icn > i{ + transition: all 0.3s ease; +} +.collapsed .collapse-icn > i{ + transform: rotate(-90deg); +} +.tree-label.badge{ + font-size: 90%; +} \ 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 52% 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 9bf5725..84f97ec 100644 --- a/konova/templates/konova/widgets/checkbox-tree-select-content.html +++ b/konova/templates/konova/widgets/tree/checkbox/checkbox-tree-select-content.html @@ -2,18 +2,23 @@ {% for code in codes %}
-
- {% include 'konova/widgets/checkbox-tree-select-content.html' %} + {% include 'konova/widgets/tree/checkbox/checkbox-tree-select-content.html' %}
\ No newline at end of file