Custom form configuration #268

Merged
tobru merged 34 commits from 165-form-configuration into main 2025-11-10 14:49:33 +00:00
6 changed files with 30 additions and 19 deletions
Showing only changes of commit ca485978b9 - Show all commits

View file

@ -192,7 +192,7 @@ class ServiceDefinitionAdminForm(forms.ModelForm):
schema = None
try:
schema = crd.resource_schema
except Exception as e:
except Exception:
pass
if not schema or not (spec_schema := schema.get("properties", {}).get("spec")):

View file

@ -15,7 +15,11 @@ 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",
),

View file

@ -31,7 +31,9 @@
</div>
{% for provider in socialaccount_providers %}
{% provider_login_url provider process=process scope=scope auth_params=auth_params as href %}
<form method="post" action="{{ href }}" class="d-flex justify-content-center">
<form method="post"
action="{{ href }}"
class="d-flex justify-content-center">
{% csrf_token %}
{{ redirect_field }}
<button type="submit"

View file

@ -42,7 +42,9 @@
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div>
<strong>{% translate "Service Unavailable" %}</strong>
<p class="mb-0">{% translate "We currently cannot offer this service. Please check back later or contact support for more information." %}</p>
<p class="mb-0">
{% translate "We currently cannot offer this service. Please check back later or contact support for more information." %}
</p>
</div>
</div>
</div>

View file

@ -4,9 +4,7 @@
{% for info in control_plane.user_info %}
<div class="info-item mb-3">
<div class="d-flex align-items-center mb-1">
<small class="text-muted fw-semibold">
{{ info.title }}
</small>
<small class="text-muted fw-semibold">{{ info.title }}</small>
{% if info.help_text %}
<i class="bi bi-info-circle ms-1 text-muted"
data-bs-toggle="popover"
@ -14,7 +12,7 @@
data-bs-placement="top"
data-bs-content="{{ info.help_text }}"
style="cursor: help;
font-size: 0.875rem;"></i>
font-size: 0.875rem"></i>
{% endif %}
</div>
<div class="bg-light-subtle p-2 rounded">

View file

@ -15,7 +15,8 @@
</button>
</div>
{% endif %}
<div id="custom-form-container" class="{% if form %}custom-crd-form{% else %}expert-crd-form{% endif %}">
<div id="custom-form-container"
class="{% if form %}custom-crd-form{% else %}expert-crd-form{% endif %}">
{% if form and form.context %}{{ form.context }}{% endif %}
{% if form and form.get_fieldsets|length == 1 %}
{# Single fieldset - render without tabs #}
@ -41,8 +42,7 @@
<ul class="nav nav-tabs" id="myTab" role="tablist">
{% for fieldset in form.get_fieldsets %}
{% if not fieldset.hidden %}
<li class="nav-item"
role="presentation">
<li class="nav-item" role="presentation">
<button class="nav-link {% if forloop.first %}active{% endif %}{% if fieldset.has_mandatory %} has-mandatory{% endif %}"
id="{{ fieldset.title|slugify }}-tab"
data-bs-toggle="tab"
@ -83,12 +83,13 @@
{% endif %}
</div>
{% if form and expert_form %}
<div id="expert-form-container" class="expert-crd-form" style="display:none;">
<div id="expert-form-container"
class="expert-crd-form"
style="display:none">
<ul class="nav nav-tabs" id="expertTab" role="tablist">
{% for fieldset in expert_form.get_fieldsets %}
{% if not fieldset.hidden %}
<li class="nav-item"
role="presentation">
<li class="nav-item" role="presentation">
<button class="nav-link {% if forloop.first %}active{% endif %}{% if fieldset.has_mandatory %} has-mandatory{% endif %}"
id="expert-{{ fieldset.title|slugify }}-tab"
data-bs-toggle="tab"
@ -129,13 +130,17 @@
</div>
{% endif %}
{% if form %}
<input type="hidden" name="active_form" id="active-form-input" value="custom">
<input type="hidden"
name="active_form"
id="active-form-input"
value="custom">
{% endif %}
<div class="col-sm-12 d-flex justify-content-end">
<input class="btn btn-primary me-1 mb-1" type="submit"
{% if form and expert_form %}formnovalidate {% endif %} {# browser form validation fails when there are fields missing/invalid that are hidden #}
value="{% if form_submit_label %}{{ form_submit_label }}{% else %}{% translate "Save" %}{% endif %}"
>
{# browser form validation fails when there are fields missing/invalid that are hidden #}
<input class="btn btn-primary me-1 mb-1"
type="submit"
{% if form and expert_form %}formnovalidate{% endif %}
value="{% if form_submit_label %}{{ form_submit_label }}{% else %}{% translate "Save" %}{% endif %}" />
</div>
</form>
{% if form %}