Per service definition dynamically configurable form (Simple Form) #165

Closed
opened 2025-08-21 07:00:39 +00:00 by tobru · 3 comments
Owner

Stories

As a user, I want to have a good understanding and accessibility of the fields in the service form, but also the full freedom to change all the parameters.

Implementation Notes

We generate the service form from the fields and structure of the OpenAPI spec of the service definition. While this works, the resulting form isn't user-friendly.

Therefore, we introduce a manually crafted (per service definition) form that is displayed and used by default. The currently automatically generated form will then be hidden behind the "Expert" button.

The configuration of this form should be stored as a JSONField form_config in the ServiceDefinition model.
Once a ServiceDefinition record has content in this field, it is used as the default form for service creation or editing.

Example (idea input):

{
    "fields": [
        {
            "name": "name",
            "type": "text",
            "label": "Instance Name",
            "help_text": "Give your instance a unique name",
            "required": true,
            "max_length": 64,
            "controlplane_field_mapping": "metada.name"
        },
        {
            "name": "alerting_email",
            "type": "email",
            "label": "Email Address to send alerts to",
            "required": false,
            "validators": ["email"],
            "controlplane_field_mapping": "spec.parameters.monitoring.email"
        },
        {
            "name": "fqdn",
            "type": "array",
            "label": "FQDNs for this service instance",
            "required": true,
            "validators": ["fqdn"],
            "generators": ["suggest_fqdn_from_name"],
            "min_values": 1,
            "max_values": 5,
            "controlplane_field_mapping": "spec.parameters.service.fqdn"
        },
        {
            "name": "backup_retention_keep_daily",
            "type": "number",
            "label": "Backup Retention: Keep Daily",
            "min_value": 1,
            "max_value": 7,
            "required": false,
            "controlplane_field_mapping": "spec.parameters.backup.retention"
        },
        {
            "name": "description",
            "type": "textarea",
            "label": "Description",
            "help_text": "Give the service a description",
            "max_length": 500,
            "rows": 4,
            "controlplane_field_mapping": "spec.parameters.description"
        },
        {
            "name": "service_level",
            "type": "choice",
            "label": "Service Level",
            "default": "besteffort",
            "choices": [
                ["guaranteed", "Guaranteed Availability"],
                ["besteffort", "Best Effort"]
            ],
            "required": true,
            "controlplane_field_mapping": "spec.parameters.service.serviceLevel"
        },
        {
            "name": "backup_state",
            "type": "checkbox",
            "label": "Enable or disable backup",
            "default": true,
            "required": true,
            "controlplane_field_mapping": "spec.parameters.backup.enabled"
        }
    ]
}

To be discussed: Should we already be able to also configure "tabs" in this configuration, to choose where the field gets displayed?

## Stories _As a user, I want to have a good understanding and accessibility of the fields in the service form, but also the full freedom to change all the parameters._ ## Implementation Notes We generate the service form from the fields and structure of the OpenAPI spec of the service definition. While this works, the resulting form isn't user-friendly. Therefore, we introduce a manually crafted (per service definition) form that is displayed and used by default. The currently automatically generated form will then be hidden behind the "Expert" button. The configuration of this form should be stored as a JSONField `form_config` in the ServiceDefinition model. Once a ServiceDefinition record has content in this field, it is used as the default form for service creation or editing. Example (idea input): ```json { "fields": [ { "name": "name", "type": "text", "label": "Instance Name", "help_text": "Give your instance a unique name", "required": true, "max_length": 64, "controlplane_field_mapping": "metada.name" }, { "name": "alerting_email", "type": "email", "label": "Email Address to send alerts to", "required": false, "validators": ["email"], "controlplane_field_mapping": "spec.parameters.monitoring.email" }, { "name": "fqdn", "type": "array", "label": "FQDNs for this service instance", "required": true, "validators": ["fqdn"], "generators": ["suggest_fqdn_from_name"], "min_values": 1, "max_values": 5, "controlplane_field_mapping": "spec.parameters.service.fqdn" }, { "name": "backup_retention_keep_daily", "type": "number", "label": "Backup Retention: Keep Daily", "min_value": 1, "max_value": 7, "required": false, "controlplane_field_mapping": "spec.parameters.backup.retention" }, { "name": "description", "type": "textarea", "label": "Description", "help_text": "Give the service a description", "max_length": 500, "rows": 4, "controlplane_field_mapping": "spec.parameters.description" }, { "name": "service_level", "type": "choice", "label": "Service Level", "default": "besteffort", "choices": [ ["guaranteed", "Guaranteed Availability"], ["besteffort", "Best Effort"] ], "required": true, "controlplane_field_mapping": "spec.parameters.service.serviceLevel" }, { "name": "backup_state", "type": "checkbox", "label": "Enable or disable backup", "default": true, "required": true, "controlplane_field_mapping": "spec.parameters.backup.enabled" } ] } ``` To be discussed: Should we already be able to also configure "tabs" in this configuration, to choose where the field gets displayed?
tobru added the
enhancement
label 2025-08-21 07:00:39 +00:00
tobru added this to the Development Planning project 2025-08-21 07:00:39 +00:00
tobru changed title from Refine Dynamic Service Form Handling to Refine Dynamic Service Form UX 2025-08-21 07:00:56 +00:00
tobru changed title from Refine Dynamic Service Form UX to Introduce Simple and Expert configuration form 2025-10-21 09:28:02 +00:00
tobru changed title from Introduce Simple and Expert configuration form to Per service definition dynamically configurable form (Simple Form) 2025-10-22 08:18:39 +00:00
Author
Owner

Some fields, like "name" should probably be hard-coded as they are mandatory for evey service. There will be other upcoming fields that will be mandatory for every service.

Some fields, like "name" should probably be hard-coded as they are mandatory for _evey_ service. There will be other upcoming fields that will be mandatory for every service.
Member

Would configuration-in-code be alright for hardcoded fields? In that case, I'd put a constant somewhere like this:

MANDATORY_FIELDS = {
        "metadata.name": {
            "name": "name",
            "type": "text",
            "label": "Instance Name",
            "help_text": "Give your instance a unique name",
            "required": true,
            "max_length": 64,
        },
}

And then the form configuration from the issue could look like this:

{
    "fields": [
        {
            "controlplane_field_mapping": "metadata.name"
        },
        {
            "name": "alerting_email",
            "type": "email",
            "label": "Email Address to send alerts to",
            "required": false,
            "validators": ["email"],
            "controlplane_field_mapping": "spec.parameters.monitoring.email"
        },
        ...
    ]
}

So we would still name the field in the form configuration, in order to be able to determine ordering/placement, but we wouldn't repeat all other information. Editing the form information would show an error or a warning if a mandatory field is missing. If necessary, the form could even override parts of the mandatory field definition (e.g. offer a more detailed help text, or even explicitly exclude a field in special cases.

Would configuration-in-code be alright for hardcoded fields? In that case, I'd put a constant somewhere like this: ```python MANDATORY_FIELDS = { "metadata.name": { "name": "name", "type": "text", "label": "Instance Name", "help_text": "Give your instance a unique name", "required": true, "max_length": 64, }, } ``` And then the form configuration from the issue could look like this: ```python { "fields": [ { "controlplane_field_mapping": "metadata.name" }, { "name": "alerting_email", "type": "email", "label": "Email Address to send alerts to", "required": false, "validators": ["email"], "controlplane_field_mapping": "spec.parameters.monitoring.email" }, ... ] } ``` So we would still name the field in the form configuration, in order to be able to determine ordering/placement, but we wouldn't repeat all other information. Editing the form information would show an error or a warning if a mandatory field is missing. If necessary, the form could even override parts of the mandatory field definition (e.g. offer a more detailed help text, or even explicitly exclude a field in special cases.
Author
Owner

Would configuration-in-code be alright for hardcoded fields?

Perfect!

> Would configuration-in-code be alright for hardcoded fields? Perfect!
tobru closed this issue 2025-11-10 14:50:44 +00:00
Sign in to join this conversation.
No milestone
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: servala/servala-portal#165
No description provided.