User forms

* refactors user/forms.py by splitting into modals package and regular forms
    * regular forms can now be found at user/forms/user.py and user/forms/team.py
    * modal forms can now be found at user/forms/modals/...
This commit is contained in:
mpeltriaux 2022-08-18 10:17:09 +02:00
parent de8d79983d
commit 05c1bf677c
7 changed files with 251 additions and 198 deletions

7
user/forms/__init__.py Normal file
View File

@ -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
"""

View File

@ -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
"""

View File

@ -1,166 +1,17 @@
""" """
Author: Michel Peltriaux Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de Contact: ksp-servicestelle@sgdnord.rlp.de
Created on: 08.07.21 Created on: 18.08.22
""" """
from dal import autocomplete from dal import autocomplete
from django import forms from django import forms
from django.db import transaction 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 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.modals import BaseModalForm, RemoveModalForm
from konova.forms import BaseForm from user.models import User, Team
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
class NewTeamModalForm(BaseModalForm): class NewTeamModalForm(BaseModalForm):
@ -347,46 +198,3 @@ class LeaveTeamModalForm(RemoveModalForm):
def save(self): def save(self):
self.instance.remove_user(self.user) 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"
]
)

62
user/forms/modals/user.py Normal file
View File

@ -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)

54
user/forms/team.py Normal file
View File

@ -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"
]
)

113
user/forms/user.py Normal file
View File

@ -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

View File

@ -5,6 +5,10 @@ from django.urls import reverse
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.mailer import Mailer from konova.utils.mailer import Mailer
from konova.utils.message_templates import FORM_INVALID 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 user.models import User, Team
from django.http import HttpRequest, Http404 from django.http import HttpRequest, Http404
from django.shortcuts import render, redirect, get_object_or_404 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.contexts import BaseContext
from konova.decorators import any_group_check, default_group_required from konova.decorators import any_group_check, default_group_required
from user.forms import UserNotificationForm, UserContactForm, UserAPITokenForm, NewTeamModalForm, EditTeamModalForm, \
RemoveTeamModalForm, TeamDataForm, LeaveTeamModalForm
@login_required @login_required