stages/prompt: add static and separator elements
This commit is contained in:
parent
e58ac7ae90
commit
ef2cdf27b3
|
@ -1,12 +1,15 @@
|
|||
"""Prompt forms"""
|
||||
from typing import Callable
|
||||
|
||||
from django import forms
|
||||
from django.contrib.admin.widgets import FilteredSelectMultiple
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from guardian.shortcuts import get_anonymous_user
|
||||
|
||||
from passbook.core.models import User
|
||||
from passbook.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
|
||||
from passbook.policies.engine import PolicyEngine
|
||||
from passbook.stages.prompt.models import Prompt, PromptStage
|
||||
from passbook.stages.prompt.models import FieldTypes, Prompt, PromptStage
|
||||
|
||||
|
||||
class PromptStageForm(forms.ModelForm):
|
||||
|
@ -57,6 +60,14 @@ class PromptForm(forms.Form):
|
|||
for field in fields:
|
||||
field: Prompt
|
||||
self.fields[field.field_key] = field.field
|
||||
# Special handling for fields with username type
|
||||
# these check for existing users with the same username
|
||||
if field.type == FieldTypes.USERNAME:
|
||||
setattr(
|
||||
self,
|
||||
f"clean_{field.field_key}",
|
||||
username_field_cleaner_generator(field),
|
||||
)
|
||||
self.field_order = sorted(fields, key=lambda x: x.order)
|
||||
|
||||
def clean(self):
|
||||
|
@ -68,3 +79,15 @@ class PromptForm(forms.Form):
|
|||
result = engine.result
|
||||
if not result.passing:
|
||||
raise forms.ValidationError(list(result.messages))
|
||||
|
||||
|
||||
def username_field_cleaner_generator(field: Prompt) -> Callable:
|
||||
"""Return a `clean_` method for `field`. Clean method checks if username is taken already."""
|
||||
|
||||
def username_field_cleaner(self: PromptForm):
|
||||
"""Check for duplicate usernames"""
|
||||
username = self.cleaned_data.get(field.field_key)
|
||||
if User.objects.filter(username=username).exists():
|
||||
raise forms.ValidationError("Username is already taken.")
|
||||
|
||||
return username_field_cleaner
|
||||
|
|
|
@ -7,25 +7,34 @@ from django.utils.translation import gettext_lazy as _
|
|||
|
||||
from passbook.flows.models import Stage
|
||||
from passbook.policies.models import PolicyBindingModel
|
||||
from passbook.stages.prompt.widgets import HorizontalRuleWidget, StaticTextWidget
|
||||
|
||||
|
||||
class FieldTypes(models.TextChoices):
|
||||
"""Field types an Prompt can be"""
|
||||
|
||||
# Simple text field
|
||||
TEXT = "text"
|
||||
TEXT = "text", _("Text: Simple Text input")
|
||||
# Same as text, but has autocomplete for password managers
|
||||
USERNAME = "username"
|
||||
EMAIL = "email"
|
||||
USERNAME = (
|
||||
"username",
|
||||
_(
|
||||
(
|
||||
"Username: Same as Text input, but checks for "
|
||||
"duplicate and prevents duplicate usernames."
|
||||
)
|
||||
),
|
||||
)
|
||||
EMAIL = "email", _("Email: Text field with Email type.")
|
||||
PASSWORD = "password" # noqa # nosec
|
||||
NUMBER = "number"
|
||||
CHECKBOX = "checkbox"
|
||||
DATE = "data"
|
||||
DATE_TIME = "data-time"
|
||||
|
||||
SEPARATOR = "separator"
|
||||
HIDDEN = "hidden"
|
||||
STATIC = "static"
|
||||
SEPARATOR = "separator", _("Separator: Static Separator Line")
|
||||
HIDDEN = "hidden", _("Hidden: Hidden field, can be used to insert data into form.")
|
||||
STATIC = "static", _("Static: Static value, displayed as-is.")
|
||||
|
||||
|
||||
class Prompt(models.Model):
|
||||
|
@ -74,9 +83,16 @@ class Prompt(models.Model):
|
|||
field_class = forms.DateInput
|
||||
if self.type == FieldTypes.DATE_TIME:
|
||||
field_class = forms.DateTimeInput
|
||||
if self.type == FieldTypes.STATIC:
|
||||
widget = StaticTextWidget(attrs=attrs)
|
||||
kwargs["initial"] = self.placeholder
|
||||
kwargs["required"] = False
|
||||
kwargs["label"] = ""
|
||||
if self.type == FieldTypes.SEPARATOR:
|
||||
widget = HorizontalRuleWidget(attrs=attrs)
|
||||
kwargs["required"] = False
|
||||
kwargs["label"] = ""
|
||||
|
||||
# TODO: Implement static
|
||||
# TODO: Implement separator
|
||||
kwargs["widget"] = widget
|
||||
return field_class(**kwargs)
|
||||
|
||||
|
|
17
passbook/stages/prompt/widgets.py
Normal file
17
passbook/stages/prompt/widgets.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
"""Prompt Widgets"""
|
||||
from django import forms
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
|
||||
class StaticTextWidget(forms.widgets.Widget):
|
||||
"""Widget to render static text"""
|
||||
|
||||
def render(self, name, value, attrs=None, renderer=None):
|
||||
return mark_safe(f"<p>{value}</p>") # nosec
|
||||
|
||||
|
||||
class HorizontalRuleWidget(forms.widgets.Widget):
|
||||
"""Widget, which renders an <hr> element"""
|
||||
|
||||
def render(self, name, value, attrs=None, renderer=None):
|
||||
return mark_safe("<hr>") # nosec
|
Reference in a new issue