Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Fix dynamic forms spec #1208

Merged
merged 3 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/src/zac/accounts/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ def update(self, instance, validated_data):
class GroupBlueprintSerializer(GroupPolymorphicSerializer):
serializer_mapping = {
object_type.name: object_type.blueprint_class
for object_type in list(object_type_registry.values())
for object_type in object_type_registry.values()
}
discriminator_field = "object_type"
group_field = "policies"
Expand Down
4 changes: 3 additions & 1 deletion backend/src/zac/camunda/dynamic_forms/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from rest_framework.utils.serializer_helpers import BindingDict

from zac.api.polymorphism import PolymorphicSerializer
from zac.core.api.serializers import EigenschapSpecificatieJsonSerializer

from ..data import Task
from ..user_tasks import usertask_context_serializer
Expand Down Expand Up @@ -57,7 +58,7 @@ class FormFieldSerializer(PolymorphicSerializer):
serializer_mapping = {
"enum": EnumSerializer,
"string": StringSerializer,
"long": IntSerializer,
"int": IntSerializer,
"boolean": BooleanSerializer,
"date": DatetimeSerializer,
}
Expand All @@ -78,6 +79,7 @@ class FormFieldSerializer(PolymorphicSerializer):
choices=list(INPUT_TYPE_MAP.values()),
required=True,
)
spec = EigenschapSpecificatieJsonSerializer(required=False, allow_null=True)


@usertask_context_serializer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,19 +156,22 @@ def test_get_context_no_eigenschappen_enum_from_camunda_values(self, m, gt):
"label": "EIGENSCHAP",
"inputType": "string",
"value": "waarde1",
"spec": None,
},
{
"name": "formfield-02",
"label": "SOMELABEL-02",
"inputType": "enum",
"value": None,
"enum": [["first", "First"], ["second", "Second"]],
"spec": None,
},
{
"name": "formfield-03",
"label": "LONG-FIELD",
"inputType": "long",
"inputType": "int",
"value": None,
"spec": None,
},
]
},
Expand Down Expand Up @@ -249,19 +252,30 @@ def test_get_context_with_eigenschap_enum_from_waardenverzameling(self, m, gt):
["waarde1", "waarde1"],
["waarde2", "waarde2"],
], # <- values from eigenschap specificatie waardenverzameling
"spec": {
"enum": [
{"label": "waarde1", "value": "waarde1"},
{"label": "waarde2", "value": "waarde2"},
],
"maxLength": 7,
"minLength": 1,
"type": "string",
},
},
{
"name": "formfield-02",
"label": "SOMELABEL-02",
"inputType": "enum",
"value": None,
"enum": [["first", "First"], ["second", "Second"]],
"spec": None,
},
{
"name": "formfield-03",
"label": "LONG-FIELD",
"inputType": "long",
"inputType": "int",
"value": None,
"spec": None,
},
]
},
Expand Down Expand Up @@ -354,19 +368,36 @@ def test_get_context_with_eigenschap_enum_from_zaaktype_attributes(self, m, gt):
["zaaktype-attribuut-01", "zaaktype-attribuut-01"],
["zaaktype-attribuut-02", "zaaktype-attribuut-02"],
], # <- values from eigenschap specificatie waardenverzameling
"spec": {
"enum": [
{
"label": "zaaktype-attribuut-01",
"value": "zaaktype-attribuut-01",
},
{
"label": "zaaktype-attribuut-02",
"value": "zaaktype-attribuut-02",
},
],
"maxLength": 7,
"minLength": 1,
"type": "string",
},
},
{
"name": "formfield-02",
"label": "SOMELABEL-02",
"inputType": "enum",
"value": None,
"enum": [["first", "First"], ["second", "Second"]],
"spec": None,
},
{
"name": "formfield-03",
"label": "LONG-FIELD",
"inputType": "long",
"inputType": "int",
"value": None,
"spec": None,
},
]
},
Expand Down Expand Up @@ -639,7 +670,7 @@ def test_validate_form_field_eigenschap_enum_from_zaaktype_attributes(self, m, g
response.json(),
{
"formfield-01": [
"A ZAAKEIGENSCHAP with `name` formfield-01 requires a maximum length of 7."
"A ZAAKEIGENSCHAP with `name`: EIGENSCHAP requires a maximum length of 7."
]
},
)
Expand Down
23 changes: 17 additions & 6 deletions backend/src/zac/camunda/dynamic_forms/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,17 @@ def get_default_field_kwargs(definition: dict):
if spec := definition.get("spec", None):
validators = []
if min_length := spec.get("min_length", None):
validators.append(minLengthValidator(min_length=min_length))

validators.append(maxLengthValidator(max_length=spec.get("max_length", 255)))
validators.append(
minLengthValidator(
min_length=min_length, eigenschap=definition["label"]
)
)

validators.append(
maxLengthValidator(
max_length=spec.get("max_length", 255), eigenschap=definition["label"]
)
)
if validators:
kwargs["validators"] = validators

Expand All @@ -71,7 +79,7 @@ def enum_field_kwargs(definition):
serializers.CharField,
get_default_field_kwargs,
),
"long": (
"int": (
serializers.IntegerField,
get_default_field_kwargs,
),
Expand All @@ -89,7 +97,7 @@ def enum_field_kwargs(definition):
INPUT_TYPE_MAP = {
"enum": "enum",
"string": "string",
"long": "long",
"long": "int",
"boolean": "boolean",
"date": "date",
}
Expand Down Expand Up @@ -168,8 +176,11 @@ def get_field_definition(field: Element) -> Dict[str, Any]:
field_definition["enum"] = choices
field_definition["input_type"] = INPUT_TYPE_MAP["enum"]
else:
if (field_type := field.attrib["type"]) not in FIELD_TYPE_MAP:
if (field_type := field.attrib["type"]) not in INPUT_TYPE_MAP:
raise NotImplementedError(f"Unknown field type '{field_type}'")
field_definition["input_type"] = INPUT_TYPE_MAP[field_type]

if not field_definition.get("spec"):
field_definition["spec"] = None

return field_definition
16 changes: 10 additions & 6 deletions backend/src/zac/camunda/dynamic_forms/validators.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

from django.utils.encoding import force_str
from django.utils.translation import ugettext_lazy as _

Expand All @@ -7,34 +9,36 @@
class minLengthValidator:
requires_context = True
message = _(
"A ZAAKEIGENSCHAP with `name` {eigenschap} requires a minimum length of {min_length}."
"A ZAAKEIGENSCHAP with `name`: {eigenschap} requires a minimum length of {min_length}."
)

def __init__(self, min_length: int = 0):
def __init__(self, min_length: int = 0, eigenschap: Optional[str] = None):
self.min_length = min_length
self.eigenschap = eigenschap

def __call__(self, value, serializer_field):
if len(force_str(value)) < self.min_length:
raise ValidationError(
self.message.format(
eigenschap=serializer_field.field_name, min_length=self.min_length
eigenschap=self.eigenschap, min_length=self.min_length
)
)


class maxLengthValidator:
requires_context = True
message = _(
"A ZAAKEIGENSCHAP with `name` {eigenschap} requires a maximum length of {max_length}."
"A ZAAKEIGENSCHAP with `name`: {eigenschap} requires a maximum length of {max_length}."
)

def __init__(self, max_length: int = 255):
def __init__(self, max_length: int = 255, eigenschap: Optional[str] = None):
self.max_length = max_length
self.eigenschap = eigenschap

def __call__(self, value, serializer_field):
if len(force_str(value)) > self.max_length:
raise ValidationError(
self.message.format(
eigenschap=serializer_field.field_name, max_length=self.max_length
eigenschap=self.eigenschap, max_length=self.max_length
)
)
2 changes: 1 addition & 1 deletion backend/src/zac/conf/includes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@
# Project applications.
"zac.elasticsearch",
"zac.accounts",
"zac.camunda",
"zac.core",
"zac.camunda",
"zac.notifications",
"zac.forms",
"zac.landing",
Expand Down
4 changes: 2 additions & 2 deletions backend/src/zac/core/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1422,7 +1422,7 @@ def to_representation(self, instance):
return ret


class SearchEigenschapSpecificatieSerializer(GroupPolymorphicSerializer):
class EigenschapSpecificatieJsonSerializer(GroupPolymorphicSerializer):
serializer_mapping = {
TypeChoices.string: StringEnumSerializer,
TypeChoices.number: NumberEnumSerializer,
Expand Down Expand Up @@ -1455,7 +1455,7 @@ class SearchEigenschapSpecificatieSerializer(GroupPolymorphicSerializer):

class SearchEigenschapSerializer(serializers.Serializer):
name = serializers.CharField(help_text=_("Name of EIGENSCHAP"))
spec = SearchEigenschapSpecificatieSerializer(
spec = EigenschapSpecificatieJsonSerializer(
label=_("property definition"),
help_text=_("JSON schema-ish specification of related ZAAK-EIGENSCHAP values."),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ <h2>{{taskContextData.task.name | capitalize}}</h2>
<!-- string-->
<gu-textarea *ngSwitchCase="'string'"
[required]="true"
[maxlength]="formField.spec.maxLength.toString()"
[control]="dynamicFormField(formField.name)"
[value]="formField.value"
id="dyn-form-str-{{formField.name}}"
></gu-textarea>
<!-- number-->
<gu-input *ngSwitchCase="'long'"
<gu-input *ngSwitchCase="'int'"
type="number"
[required]="true"
[control]="dynamicFormField(formField.name)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export class DynamicFormComponent implements OnChanges {
case 'date':
value = this.datePipe.transform(value, "yyyy-MM-dd hh:mm:ss");
break;
case 'long': value = parseInt(value, 10); break;
case 'int': value = parseInt(value, 10); break;
}
formData[control] = value;
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@ export interface ZaakInformatie {
export interface FormField {
name: string;
label: string;
inputType: 'enum' | 'string' | 'long' | 'boolean' | 'date';
inputType: 'enum' | 'string' | 'int' | 'boolean' | 'date';
value: string | number | boolean;
enum?: Array<string[]>;
spec: {
maxLength?: number;
minLength?: number;
type: string;
}
}

interface InformatieObjectType {
Expand Down
Loading