diff --git a/user/forms/__init__.py b/user/forms/__init__.py new file mode 100644 index 00000000..ca978536 --- /dev/null +++ b/user/forms/__init__.py @@ -0,0 +1,7 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: ksp-servicestelle@sgdnord.rlp.de +Created on: 18.08.22 + +""" diff --git a/user/forms/modals/__init__.py b/user/forms/modals/__init__.py new file mode 100644 index 00000000..ca978536 --- /dev/null +++ b/user/forms/modals/__init__.py @@ -0,0 +1,7 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: ksp-servicestelle@sgdnord.rlp.de +Created on: 18.08.22 + +""" diff --git a/user/forms.py b/user/forms/modals/team.py similarity index 52% rename from user/forms.py rename to user/forms/modals/team.py index 0649eaf3..d63a2306 100644 --- a/user/forms.py +++ b/user/forms/modals/team.py @@ -1,166 +1,17 @@ """ Author: Michel Peltriaux Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany -Contact: michel.peltriaux@sgdnord.rlp.de -Created on: 08.07.21 +Contact: ksp-servicestelle@sgdnord.rlp.de +Created on: 18.08.22 """ from dal import autocomplete from django import forms from django.db import transaction -from django.urls import reverse, reverse_lazy +from django.urls import reverse from django.utils.translation import gettext_lazy as _ - -from api.models import APIUserToken -from intervention.inputs import GenerateInput -from user.models import User, UserNotification, Team - from konova.forms.modals import BaseModalForm, RemoveModalForm -from konova.forms import BaseForm - - -class UserNotificationForm(BaseForm): - """ Form for changing the notification settings of a user - - """ - notifications = forms.MultipleChoiceField( - label_suffix="", - label=_("Notifications"), - required=False, # allow total disabling of all notifications - help_text=_("Select the situations when you want to receive a notification"), - widget=forms.CheckboxSelectMultiple( - attrs={ - "class": "list-unstyled", - } - ), - choices=[] - ) - - def __init__(self, user: User, *args, **kwargs): - super().__init__(*args, **kwargs) - self.user = user - self.form_title = _("Edit notifications") - self.form_caption = _("") - self.action_url = reverse("user:notifications") - self.cancel_redirect = reverse("user:index") - - # Insert all notifications into form field by creating choices as tuples - notifications = UserNotification.objects.filter( - is_active=True, - ) - choices = [] - for n in notifications: - choices.append( - (n.id, _(n.name)) - ) - self.fields["notifications"].choices = choices - - users_current_notifications = self.user.notifications.all() - users_current_notifications = [str(n.id) for n in users_current_notifications] - self.fields["notifications"].initial = users_current_notifications - - def save(self): - """ Stores the changes in the user konova_extension - - Returns: - - """ - selected_notification_ids = self.cleaned_data.get("notifications", []) - notifications = UserNotification.objects.filter( - id__in=selected_notification_ids, - ) - self.user.notifications.set(notifications) - - -class UserContactForm(BaseModalForm): - name = forms.CharField( - label=_("Username"), - label_suffix="", - required=False, - widget=forms.TextInput( - attrs={ - "readonly": True, - "class": "form-control", - } - ), - ) - person_name = forms.CharField( - label=_("Person name"), - label_suffix="", - required=False, - widget=forms.TextInput( - attrs={ - "readonly": True, - "class": "form-control", - } - ), - ) - mail = forms.EmailField( - label=_("E-Mail"), - label_suffix="", - required=False, - widget=forms.TextInput( - attrs={ - "readonly": True, - "class": "form-control", - } - ), - ) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.render_submit = False - self.form_title = _("User contact data") - self.form_caption = "" - - self.initialize_form_field("name", self.instance.username) - self.initialize_form_field("person_name", "{} {}".format(self.instance.first_name, self.instance.last_name)) - self.initialize_form_field("mail", self.instance.email) - - -class UserAPITokenForm(BaseForm): - token = forms.CharField( - label=_("Token"), - label_suffix="", - max_length=255, - required=True, - help_text=_("Generated automatically"), - widget=GenerateInput( - attrs={ - "class": "form-control", - "url": reverse_lazy("api:generate-new-token"), - } - ) - ) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.form_title = _("Create new token") - self.form_caption = _("A new token needs to be validated by an administrator!") - - self.action_url = reverse("user:api-token") - self.cancel_redirect = reverse("user:index") - - # Make direct token editing by user impossible. Instead set the proper url for generating a new token - self.initialize_form_field("token", None) - self.fields["token"].widget.attrs["readonly"] = True - - def save(self): - """ Saves the form data - - Returns: - api_token (APIUserToken) - """ - user = self.instance - new_token = self.cleaned_data["token"] - if user.api_token is not None: - user.api_token.delete() - new_token = APIUserToken.objects.create( - token=new_token - ) - user.api_token = new_token - user.save() - return new_token +from user.models import User, Team class NewTeamModalForm(BaseModalForm): @@ -347,46 +198,3 @@ class LeaveTeamModalForm(RemoveModalForm): def save(self): self.instance.remove_user(self.user) - - -class TeamDataForm(BaseModalForm): - name = forms.CharField( - label_suffix="", - label=_("Team name"), - max_length=500, - required=False, - widget=forms.TextInput( - attrs={ - "placeholder": _("Team name"), - "class": "form-control", - } - ) - ) - description = forms.CharField( - label_suffix="", - required=False, - label=_("Description"), - widget=forms.Textarea( - attrs={ - "rows": 5, - "class": "form-control" - } - ) - ) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.form_title = _("Team") - self.form_caption = "" - self.render_submit = False - form_data = { - "name": self.instance.name, - "description": self.instance.description, - } - self.load_initial_data( - form_data, - [ - "name", - "description" - ] - ) \ No newline at end of file diff --git a/user/forms/modals/user.py b/user/forms/modals/user.py new file mode 100644 index 00000000..d5631050 --- /dev/null +++ b/user/forms/modals/user.py @@ -0,0 +1,62 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: ksp-servicestelle@sgdnord.rlp.de +Created on: 18.08.22 + +""" +from django import forms +from django.utils.translation import gettext_lazy as _ + +from konova.forms.modals import BaseModalForm + + +class UserContactForm(BaseModalForm): + def save(self): + # Readonly form. No saving needed + pass + + name = forms.CharField( + label=_("Username"), + label_suffix="", + required=False, + widget=forms.TextInput( + attrs={ + "readonly": True, + "class": "form-control", + } + ), + ) + person_name = forms.CharField( + label=_("Person name"), + label_suffix="", + required=False, + widget=forms.TextInput( + attrs={ + "readonly": True, + "class": "form-control", + } + ), + ) + mail = forms.EmailField( + label=_("E-Mail"), + label_suffix="", + required=False, + widget=forms.TextInput( + attrs={ + "readonly": True, + "class": "form-control", + } + ), + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.render_submit = False + self.form_title = _("User contact data") + self.form_caption = "" + + self.initialize_form_field("name", self.instance.username) + self.initialize_form_field("person_name", "{} {}".format(self.instance.first_name, self.instance.last_name)) + self.initialize_form_field("mail", self.instance.email) + diff --git a/user/forms/team.py b/user/forms/team.py new file mode 100644 index 00000000..dab89842 --- /dev/null +++ b/user/forms/team.py @@ -0,0 +1,54 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: ksp-servicestelle@sgdnord.rlp.de +Created on: 18.08.22 + +""" +from django import forms +from django.utils.translation import gettext_lazy as _ + +from konova.forms.modals import BaseModalForm + + +class TeamDataForm(BaseModalForm): + name = forms.CharField( + label_suffix="", + label=_("Team name"), + max_length=500, + required=False, + widget=forms.TextInput( + attrs={ + "placeholder": _("Team name"), + "class": "form-control", + } + ) + ) + description = forms.CharField( + label_suffix="", + required=False, + label=_("Description"), + widget=forms.Textarea( + attrs={ + "rows": 5, + "class": "form-control" + } + ) + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("Team") + self.form_caption = "" + self.render_submit = False + form_data = { + "name": self.instance.name, + "description": self.instance.description, + } + self.load_initial_data( + form_data, + [ + "name", + "description" + ] + ) \ No newline at end of file diff --git a/user/forms/user.py b/user/forms/user.py new file mode 100644 index 00000000..99afc372 --- /dev/null +++ b/user/forms/user.py @@ -0,0 +1,113 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: ksp-servicestelle@sgdnord.rlp.de +Created on: 18.08.22 + +""" +from django import forms +from django.urls import reverse, reverse_lazy +from django.utils.translation import gettext_lazy as _ + +from api.models import APIUserToken +from intervention.inputs import GenerateInput +from konova.forms import BaseForm +from user.models import User, UserNotification + + +class UserNotificationForm(BaseForm): + """ Form for changing the notification settings of a user + + """ + notifications = forms.MultipleChoiceField( + label_suffix="", + label=_("Notifications"), + required=False, # allow total disabling of all notifications + help_text=_("Select the situations when you want to receive a notification"), + widget=forms.CheckboxSelectMultiple( + attrs={ + "class": "list-unstyled", + } + ), + choices=[] + ) + + def __init__(self, user: User, *args, **kwargs): + super().__init__(*args, **kwargs) + self.user = user + self.form_title = _("Edit notifications") + self.form_caption = _("") + self.action_url = reverse("user:notifications") + self.cancel_redirect = reverse("user:index") + + # Insert all notifications into form field by creating choices as tuples + notifications = UserNotification.objects.filter( + is_active=True, + ) + choices = [] + for n in notifications: + choices.append( + (n.id, _(n.name)) + ) + self.fields["notifications"].choices = choices + + users_current_notifications = self.user.notifications.all() + users_current_notifications = [str(n.id) for n in users_current_notifications] + self.fields["notifications"].initial = users_current_notifications + + def save(self): + """ Stores the changes in the user konova_extension + + Returns: + + """ + selected_notification_ids = self.cleaned_data.get("notifications", []) + notifications = UserNotification.objects.filter( + id__in=selected_notification_ids, + ) + self.user.notifications.set(notifications) + + +class UserAPITokenForm(BaseForm): + token = forms.CharField( + label=_("Token"), + label_suffix="", + max_length=255, + required=True, + help_text=_("Generated automatically"), + widget=GenerateInput( + attrs={ + "class": "form-control", + "url": reverse_lazy("api:generate-new-token"), + } + ) + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("Create new token") + self.form_caption = _("A new token needs to be validated by an administrator!") + + self.action_url = reverse("user:api-token") + self.cancel_redirect = reverse("user:index") + + # Make direct token editing by user impossible. Instead set the proper url for generating a new token + self.initialize_form_field("token", None) + self.fields["token"].widget.attrs["readonly"] = True + + def save(self): + """ Saves the form data + + Returns: + api_token (APIUserToken) + """ + user = self.instance + new_token = self.cleaned_data["token"] + if user.api_token is not None: + user.api_token.delete() + new_token = APIUserToken.objects.create( + token=new_token + ) + user.api_token = new_token + user.save() + return new_token \ No newline at end of file diff --git a/user/views.py b/user/views.py index 2c5b86a1..7e2d21e6 100644 --- a/user/views.py +++ b/user/views.py @@ -5,6 +5,10 @@ from django.urls import reverse from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.mailer import Mailer from konova.utils.message_templates import FORM_INVALID +from user.forms.modals.team import NewTeamModalForm, EditTeamModalForm, RemoveTeamModalForm, LeaveTeamModalForm +from user.forms.modals.user import UserContactForm +from user.forms.team import TeamDataForm +from user.forms.user import UserNotificationForm, UserAPITokenForm from user.models import User, Team from django.http import HttpRequest, Http404 from django.shortcuts import render, redirect, get_object_or_404 @@ -12,8 +16,6 @@ from django.utils.translation import gettext_lazy as _ from konova.contexts import BaseContext from konova.decorators import any_group_check, default_group_required -from user.forms import UserNotificationForm, UserContactForm, UserAPITokenForm, NewTeamModalForm, EditTeamModalForm, \ - RemoveTeamModalForm, TeamDataForm, LeaveTeamModalForm @login_required