stages/identification: replace buggy FilteredSelectMultiple with ArrayFieldSelectMultiple
This commit is contained in:
parent
516455f482
commit
8f585eca70
|
@ -1,9 +1,35 @@
|
||||||
"""YAML fields"""
|
"""Additional fields"""
|
||||||
import yaml
|
import yaml
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.utils.datastructures import MultiValueDict
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
class ArrayFieldSelectMultiple(forms.SelectMultiple):
|
||||||
|
"""This is a Form Widget for use with a Postgres ArrayField. It implements
|
||||||
|
a multi-select interface that can be given a set of `choices`.
|
||||||
|
You can provide a `delimiter` keyword argument to specify the delimeter used.
|
||||||
|
|
||||||
|
https://gist.github.com/stephane/00e73c0002de52b1c601"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
# Accept a `delimiter` argument, and grab it (defaulting to a comma)
|
||||||
|
self.delimiter = kwargs.pop("delimiter", ",")
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def value_from_datadict(self, data, files, name):
|
||||||
|
if isinstance(data, MultiValueDict):
|
||||||
|
# Normally, we'd want a list here, which is what we get from the
|
||||||
|
# SelectMultiple superclass, but the SimpleArrayField expects to
|
||||||
|
# get a delimited string, so we're doing a little extra work.
|
||||||
|
return self.delimiter.join(data.getlist(name))
|
||||||
|
|
||||||
|
return data.get(name)
|
||||||
|
|
||||||
|
def get_context(self, name, value, attrs):
|
||||||
|
return super().get_context(name, value.split(self.delimiter), attrs)
|
||||||
|
|
||||||
|
|
||||||
class CodeMirrorWidget(forms.Textarea):
|
class CodeMirrorWidget(forms.Textarea):
|
||||||
"""Custom Textarea-based Widget that triggers a CodeMirror editor"""
|
"""Custom Textarea-based Widget that triggers a CodeMirror editor"""
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
"""passbook flows identification forms"""
|
"""passbook flows identification forms"""
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.admin.widgets import FilteredSelectMultiple
|
|
||||||
from django.core.validators import validate_email
|
from django.core.validators import validate_email
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from structlog import get_logger
|
from structlog import get_logger
|
||||||
|
|
||||||
|
from passbook.admin.fields import ArrayFieldSelectMultiple
|
||||||
from passbook.flows.models import Flow, FlowDesignation
|
from passbook.flows.models import Flow, FlowDesignation
|
||||||
from passbook.lib.utils.ui import human_list
|
from passbook.lib.utils.ui import human_list
|
||||||
from passbook.stages.identification.models import IdentificationStage, UserFields
|
from passbook.stages.identification.models import IdentificationStage, UserFields
|
||||||
|
@ -37,9 +37,7 @@ class IdentificationStageForm(forms.ModelForm):
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
"name": forms.TextInput(),
|
"name": forms.TextInput(),
|
||||||
"user_fields": FilteredSelectMultiple(
|
"user_fields": ArrayFieldSelectMultiple(choices=UserFields.choices),
|
||||||
_("fields"), False, choices=UserFields.choices
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,12 @@ class IdentificationStage(Stage):
|
||||||
|
|
||||||
user_fields = ArrayField(
|
user_fields = ArrayField(
|
||||||
models.CharField(max_length=100, choices=UserFields.choices),
|
models.CharField(max_length=100, choices=UserFields.choices),
|
||||||
help_text=_("Fields of the user object to match against."),
|
help_text=_(
|
||||||
|
(
|
||||||
|
"Fields of the user object to match against. "
|
||||||
|
"(Hold shift to select multiple options)"
|
||||||
|
)
|
||||||
|
),
|
||||||
)
|
)
|
||||||
template = models.TextField(choices=Templates.choices)
|
template = models.TextField(choices=Templates.choices)
|
||||||
|
|
||||||
|
|
|
@ -7342,7 +7342,8 @@ definitions:
|
||||||
type: string
|
type: string
|
||||||
minLength: 1
|
minLength: 1
|
||||||
user_fields:
|
user_fields:
|
||||||
description: Fields of the user object to match against.
|
description: Fields of the user object to match against. (Hold shift to select
|
||||||
|
multiple options)
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
title: User fields
|
title: User fields
|
||||||
|
@ -7350,6 +7351,10 @@ definitions:
|
||||||
enum:
|
enum:
|
||||||
- email
|
- email
|
||||||
- username
|
- username
|
||||||
|
case_insensitive_matching:
|
||||||
|
title: Case insensitive matching
|
||||||
|
description: When enabled, user fields are matched regardless of their casing.
|
||||||
|
type: boolean
|
||||||
template:
|
template:
|
||||||
title: Template
|
title: Template
|
||||||
type: string
|
type: string
|
||||||
|
|
Reference in New Issue