diff --git a/intervention/forms/modalForms.py b/intervention/forms/modalForms.py index 0b72ae84..978360da 100644 --- a/intervention/forms/modalForms.py +++ b/intervention/forms/modalForms.py @@ -10,7 +10,7 @@ from django.core.exceptions import ObjectDoesNotExist from konova.utils.message_templates import DEDUCTION_ADDED, REVOCATION_ADDED, DEDUCTION_REMOVED, DEDUCTION_EDITED, \ REVOCATION_EDITED -from user.models import User +from user.models import User, Team from user.models import UserActionLogEntry from django.db import transaction from django import forms @@ -37,6 +37,20 @@ class ShareModalForm(BaseModalForm): } ) ) + team_select = forms.ModelMultipleChoiceField( + label=_("Add team to share with"), + label_suffix="", + help_text=_("Multiple selection possible - You can only select teams which do not already have access."), + required=False, + queryset=Team.objects.all(), + widget=autocomplete.ModelSelect2Multiple( + url="share-team-autocomplete", + attrs={ + "data-placeholder": _("Click for selection"), + "data-minimum-input-length": 3, + }, + ), + ) user_select = forms.ModelMultipleChoiceField( label=_("Add user to share with"), label_suffix="", @@ -97,6 +111,13 @@ class ShareModalForm(BaseModalForm): self.disable_form_field("users") self._add_user_choices_to_field() + self._add_teams_to_field() + + def _add_teams_to_field(self): + form_data = { + "teams": [] + } + self.load_initial_data(form_data) def _add_user_choices_to_field(self): """ Transforms the instance's sharing users into a list for the form field diff --git a/konova/autocompletes.py b/konova/autocompletes.py index f1775b5f..9b1be2d3 100644 --- a/konova/autocompletes.py +++ b/konova/autocompletes.py @@ -11,7 +11,7 @@ from dal_select2.views import Select2QuerySetView, Select2GroupQuerySetView from django.core.exceptions import ImproperlyConfigured from konova.utils.message_templates import UNGROUPED -from user.models import User +from user.models import User, Team from django.db.models import Q from codelist.models import KonovaCode @@ -69,9 +69,8 @@ class InterventionAutocomplete(Select2QuerySetView): class ShareUserAutocomplete(Select2QuerySetView): - """ Autocomplete for intervention entries + """ Autocomplete for share with single users - Only returns entries that are accessible for the requesting user """ def get_queryset(self): @@ -93,6 +92,23 @@ class ShareUserAutocomplete(Select2QuerySetView): return qs +class ShareTeamAutocomplete(Select2QuerySetView): + """ Autocomplete for share with teams + + """ + def get_queryset(self): + if self.request.user.is_anonymous: + return Team.objects.none() + if self.q: + # Due to privacy concerns only a full username match will return the proper user entry + qs = Team.objects.filter( + Q(name__icontains=self.q) + ).order_by( + "name" + ) + return qs + + class KonovaCodeAutocomplete(Select2GroupQuerySetView): """ Provides simple autocomplete functionality for codes diff --git a/konova/urls.py b/konova/urls.py index 68256e7a..1cd8851d 100644 --- a/konova/urls.py +++ b/konova/urls.py @@ -20,7 +20,7 @@ from django.urls import path, include from konova.autocompletes import EcoAccountAutocomplete, \ InterventionAutocomplete, CompensationActionCodeAutocomplete, BiotopeCodeAutocomplete, LawCodeAutocomplete, \ RegistrationOfficeCodeAutocomplete, ConservationOfficeCodeAutocomplete, ProcessTypeCodeAutocomplete, \ - ShareUserAutocomplete, BiotopeExtraCodeAutocomplete, CompensationActionDetailCodeAutocomplete + ShareUserAutocomplete, BiotopeExtraCodeAutocomplete, CompensationActionDetailCodeAutocomplete, ShareTeamAutocomplete from konova.settings import SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY, DEBUG from konova.sso.sso import KonovaSSOClient from konova.views import logout_view, home_view @@ -52,6 +52,7 @@ urlpatterns = [ path("atcmplt/codes/reg-off", RegistrationOfficeCodeAutocomplete.as_view(), name="codes-registration-office-autocomplete"), path("atcmplt/codes/cons-off", ConservationOfficeCodeAutocomplete.as_view(), name="codes-conservation-office-autocomplete"), path("atcmplt/share/u", ShareUserAutocomplete.as_view(), name="share-user-autocomplete"), + path("atcmplt/share/t", ShareTeamAutocomplete.as_view(), name="share-team-autocomplete"), ] if DEBUG: diff --git a/user/migrations/0003_team.py b/user/migrations/0003_team.py new file mode 100644 index 00000000..6f7ac90a --- /dev/null +++ b/user/migrations/0003_team.py @@ -0,0 +1,29 @@ +# Generated by Django 3.1.3 on 2022-02-17 10:22 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('user', '0002_user_api_token'), + ] + + operations = [ + migrations.CreateModel( + name='Team', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('name', models.CharField(blank=True, max_length=500, null=True)), + ('description', models.TextField(blank=True, null=True)), + ('admin', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ('users', models.ManyToManyField(blank=True, related_name='teams', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ]