diff --git a/src/servala/core/crd.py b/src/servala/core/crd.py index 6ae70c9..8c31a27 100644 --- a/src/servala/core/crd.py +++ b/src/servala/core/crd.py @@ -560,7 +560,7 @@ class CustomFormMixin(FormGeneratorMixin): field = self.fields[field_name] field_type = field_config.get("type") - field.label = field_config.get("label", field_name) + field.label = field_config.get("label", field_config["name"]) field.help_text = field_config.get("help_text", "") field.required = field_config.get("required", False) diff --git a/src/servala/core/forms.py b/src/servala/core/forms.py index dacd956..36f8be5 100644 --- a/src/servala/core/forms.py +++ b/src/servala/core/forms.py @@ -192,7 +192,7 @@ class ServiceDefinitionAdminForm(forms.ModelForm): schema = None try: schema = crd.resource_schema - except Exception: + except Exception as e: pass if not schema or not (spec_schema := schema.get("properties", {}).get("spec")): diff --git a/src/servala/core/migrations/0013_add_form_config.py b/src/servala/core/migrations/0013_add_form_config.py index 2819a6c..bd35891 100644 --- a/src/servala/core/migrations/0013_add_form_config.py +++ b/src/servala/core/migrations/0013_add_form_config.py @@ -15,11 +15,7 @@ class Migration(migrations.Migration): name="form_config", field=models.JSONField( blank=True, - help_text=( - "Optional custom form configuration. When provided, this configuration will " - "be used to render the service form instead of auto-generating it from the OpenAPI spec. " - 'Format: {"fieldsets": [{"title": "Section", "fields": [{...}]}]}' - ), + help_text='Optional custom form configuration. When provided, this configuration will be used to render the service form instead of auto-generating it from the OpenAPI spec. Format: {"fieldsets": [{"title": "Section", "fields": [{...}]}]}', null=True, verbose_name="Form Configuration", ), diff --git a/src/servala/core/schemas/form_config_schema.json b/src/servala/core/schemas/form_config_schema.json index 15f79df..1049ed8 100644 --- a/src/servala/core/schemas/form_config_schema.json +++ b/src/servala/core/schemas/form_config_schema.json @@ -23,8 +23,13 @@ "minItems": 1, "items": { "type": "object", - "required": ["type", "label", "controlplane_field_mapping"], + "required": ["name", "type", "label", "controlplane_field_mapping"], "properties": { + "name": { + "type": "string", + "description": "Unique field name/identifier", + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$" + }, "type": { "type": "string", "description": "Field type", @@ -92,6 +97,14 @@ "type": "string", "enum": ["email", "fqdn", "url", "ipv4", "ipv6"] } + }, + "generators": { + "type": "array", + "description": "Array of generator function names (for future use)", + "items": { + "type": "string", + "enum": ["suggest_fqdn_from_name"] + } } } } diff --git a/src/servala/frontend/templates/account/login.html b/src/servala/frontend/templates/account/login.html index 906a9fa..f4ca590 100644 --- a/src/servala/frontend/templates/account/login.html +++ b/src/servala/frontend/templates/account/login.html @@ -31,9 +31,7 @@ {% for provider in socialaccount_providers %} {% provider_login_url provider process=process scope=scope auth_params=auth_params as href %} -
+ {% csrf_token %} {{ redirect_field }} {% endif %} -
+
{% if form and form.context %}{{ form.context }}{% endif %} {% if form and form.get_fieldsets|length == 1 %} {# Single fieldset - render without tabs #} @@ -42,7 +41,8 @@