snapshot: preserve dynamic builder and section ordering work

This commit is contained in:
Md Bayazid Bostame
2026-03-27 16:54:11 +01:00
parent fdc27f2123
commit 30877ed8ee
13 changed files with 1391 additions and 365 deletions

View File

@@ -32,81 +32,6 @@
<div id="status-message" class="status" aria-live="polite"></div>
<nav class="builder-quicknav" aria-label="{% trans 'Bereiche' %}">
<a href="#builder-structure">{% trans "Reihenfolge" %}</a>
<a href="#builder-rules">{% trans "Regeln" %}</a>
<a href="#builder-content">{% trans "Optionen & Texte" %}</a>
</nav>
<section class="builder-overview">
<article class="builder-stat-card">
<span class="builder-stat-label">{% trans "Fixe Kernfelder" %}</span>
<strong>{{ builder_summary.locked_field_count }}</strong>
</article>
<article class="builder-stat-card">
<span class="builder-stat-label">{% trans "Konfigurierbar" %}</span>
<strong>{{ builder_summary.configurable_field_count }}</strong>
</article>
<article class="builder-stat-card">
<span class="builder-stat-label">{% trans "Aktuell ausgeblendet" %}</span>
<strong>{{ builder_summary.hidden_field_count }}</strong>
</article>
<article class="builder-stat-card">
<span class="builder-stat-label">{% trans "Eigene Felder" %}</span>
<strong>{{ builder_summary.custom_field_count }}</strong>
</article>
{% if form_type == 'onboarding' %}
<article class="builder-stat-card">
<span class="builder-stat-label">{% trans "Versteckte Abschnitte" %}</span>
<strong>{{ builder_summary.hidden_section_count }}</strong>
</article>
{% endif %}
</section>
<section class="builder-preset-bar">
<form class="builder-preset-form" method="post" action="/admin-tools/form-builder/?form_type={{ form_type }}&option_category={{ selected_option_category }}">
{% csrf_token %}
<input type="hidden" name="builder_action" value="apply_preset" />
<label class="builder-preset-label" for="preset_key">{% trans "Vorlage anwenden" %}</label>
<select id="preset_key" name="preset_key">
{% for preset_key, preset in available_presets.items %}
<option value="{{ preset_key }}">{{ preset.label }}</option>
{% endfor %}
</select>
<button class="btn btn-secondary" type="submit">{% trans "Anwenden" %}</button>
</form>
</section>
<details class="builder-panel builder-accordion js-single-accordion" data-accordion-group="builder-panels" id="builder-preview" {% if active_panel == 'builder-preview' %}open{% endif %}>
<summary class="builder-panel-summary">
<div class="builder-panel-head">
<div>
<h2>{% trans "Live-Vorschau" %}</h2>
</div>
<span class="builder-panel-toggle">{% trans "Öffnen" %}</span>
</div>
</summary>
<div class="builder-panel-body">
<div class="preview-shell">
{% for section in preview_sections %}
<section class="preview-section">
<div class="preview-section-head">
<h3>{{ section.title }}</h3>
<span class="column-count">{% blocktrans trimmed with count=section.items|length %}{{ count }} Feld/Felder{% endblocktrans %}</span>
</div>
<div class="preview-chip-list">
{% for item in section.items %}
<span class="preview-chip{% if item.locked %} is-locked{% endif %}">{{ item.label }}</span>
{% empty %}
<span class="mini">{% trans "Keine sichtbaren Felder." %}</span>
{% endfor %}
</div>
</section>
{% endfor %}
</div>
</div>
</details>
<details class="builder-panel builder-accordion js-single-accordion" data-accordion-group="builder-panels" id="builder-structure" {% if active_panel == 'builder-structure' %}open{% endif %}>
<summary class="builder-panel-summary">
<div class="builder-panel-head">
@@ -158,46 +83,63 @@
</summary>
<div class="builder-panel-body">
<div class="builder-rule-layout">
<section class="options-panel">
<div class="options-head">
<h2>{% trans "Abschnitte steuern" %}</h2>
</div>
<div class="builder-stack-layout">
<details class="options-panel nested-accordion js-single-accordion" data-accordion-group="builder-rules-subpanels" {% if active_rules_panel == 'section-rules' %}open{% endif %}>
<summary class="nested-accordion-summary">
<div class="options-head">
<h2>{% trans "Abschnitte steuern" %}</h2>
<span class="builder-panel-toggle">{% trans "Öffnen" %}</span>
</div>
</summary>
<div class="nested-accordion-body">
<form method="post" action="/admin-tools/form-builder/?form_type={{ form_type }}&option_category={{ selected_option_category }}">
{% csrf_token %}
<div class="section-rule-grid">
<div class="section-rule-grid" id="section-rule-grid">
{% for section in section_rule_items %}
<label class="section-rule-card{% if section.locked %} is-locked{% endif %}">
<article
class="section-rule-card{% if section.locked %} is-locked{% endif %}"
draggable="true"
data-section-key="{{ section.key }}"
>
<input type="hidden" name="section_order" value="{{ section.key }}" />
<div class="section-rule-drag" aria-hidden="true" title="{% trans 'Zum Verschieben ziehen' %}">⋮⋮</div>
<div class="section-rule-copy">
<strong>{{ section.title }}</strong>
<span>{% blocktrans trimmed with count=section.field_count %}{{ count }} Feld/Felder in diesem Abschnitt.{% endblocktrans %}</span>
</div>
<div class="section-rule-toggle">
<input
type="checkbox"
name="section_visible_{{ section.key }}"
{% if section.is_visible %}checked{% endif %}
{% if section.locked %}disabled{% endif %}
/>
<label class="section-rule-checkbox">
<input
type="checkbox"
name="section_visible_{{ section.key }}"
{% if section.is_visible %}checked{% endif %}
{% if section.locked %}disabled{% endif %}
/>
</label>
<span class="badge {% if section.is_visible %}required{% else %}hidden{% endif %}">
{% if section.locked %}{% trans "Fix" %}
{% elif section.is_visible %}{% trans "Sichtbar" %}
{% else %}{% trans "Ausgeblendet" %}{% endif %}
</span>
</div>
</label>
</article>
{% endfor %}
</div>
<div class="options-actions">
<button class="btn btn-primary" type="submit" name="builder_action" value="save_section_rules">{% trans "Abschnittsregeln speichern" %}</button>
</div>
</form>
</section>
<section class="options-panel">
<div class="options-head">
<h2>{% trans "Feldregeln verwalten" %}</h2>
</div>
</details>
<details class="options-panel nested-accordion js-single-accordion" data-accordion-group="builder-rules-subpanels" {% if active_rules_panel == 'field-rules' %}open{% endif %}>
<summary class="nested-accordion-summary">
<div class="options-head">
<h2>{% trans "Feldregeln verwalten" %}</h2>
<span class="builder-panel-toggle">{% trans "Öffnen" %}</span>
</div>
</summary>
<div class="nested-accordion-body">
<form method="post" action="/admin-tools/form-builder/?form_type={{ form_type }}&option_category={{ selected_option_category }}">
{% csrf_token %}
<div class="field-rule-groups">
@@ -250,61 +192,104 @@
<button class="btn btn-primary" type="submit" name="builder_action" value="save_field_rules">{% trans "Feldregeln speichern" %}</button>
</div>
</form>
</section>
</div>
</details>
{% if form_type == 'onboarding' %}
<section class="options-panel">
<div class="options-head">
<h2>{% trans "Bedingte Logik" %}</h2>
</div>
<details class="options-panel nested-accordion js-single-accordion" data-accordion-group="builder-rules-subpanels" {% if active_rules_panel == 'conditional-rules' %}open{% endif %}>
<summary class="nested-accordion-summary">
<div class="options-head">
<h2>{% trans "Bedingte Logik" %}</h2>
<span class="builder-panel-toggle">{% trans "Öffnen" %}</span>
</div>
</summary>
<div class="nested-accordion-body">
<form method="post" action="/admin-tools/form-builder/?form_type={{ form_type }}&option_category={{ selected_option_category }}">
{% csrf_token %}
<div class="field-rule-groups">
<div class="conditional-rule-grid">
{% for item in conditional_rule_items %}
<section class="field-rule-group">
<div class="field-rule-group-head">
<h3>{{ item.title }}</h3>
<span class="column-count">{{ item.target_fields|join:", " }}</span>
</div>
<div class="field-rule-list">
<div class="field-rule-row">
<div class="field-rule-main">
<strong>{{ item.title }}</strong>
<div class="mini">{{ item.description }}</div>
</div>
<label class="field-rule-control">
<span>{% trans "Aktiv" %}</span>
<input type="checkbox" name="conditional_active_{{ item.target_key }}" {% if item.is_active %}checked{% endif %} />
</label>
<section class="conditional-rule-card">
<div class="conditional-rule-head">
<div class="conditional-rule-head-main">
<span class="conditional-rule-eyebrow">{% trans "Sichtbarkeit" %}</span>
<h3>{{ item.title }}</h3>
{% if item.description %}
<p class="mini">{{ item.description }}</p>
{% endif %}
</div>
{% for clause in item.clauses %}
<div class="field-rule-row">
<div class="field-rule-main">
<strong>{% blocktrans trimmed with number=forloop.counter %}Bedingung {{ number }}{% endblocktrans %}</strong>
<label class="conditional-toggle">
<span>{% trans "Aktiv" %}</span>
<input type="checkbox" name="conditional_active_{{ item.target_key }}" {% if item.is_active %}checked{% endif %} />
</label>
</div>
<div class="conditional-targets">
<span class="conditional-target-label">{% trans "Steuert" %}</span>
<div class="conditional-target-chips">
{% for field_name in item.target_fields %}
<span class="preview-chip">{{ field_name }}</span>
{% empty %}
<span class="mini">{% trans "Keine Ziel-Felder." %}</span>
{% endfor %}
</div>
</div>
<div class="conditional-clause-list">
{% with first_clause=item.clauses.0 second_clause=item.clauses.1 %}
<div class="conditional-clause-row">
<div class="conditional-clause-index">
{% trans "Wenn" %}
</div>
<label class="field-rule-control">
<label class="conditional-clause-control conditional-clause-field">
<span>{% trans "Feld" %}</span>
<select name="conditional_field_{{ item.target_key }}_{{ forloop.counter0 }}">
<select name="conditional_field_{{ item.target_key }}_0">
<option value="">{% trans "Keine" %}</option>
{% for value, label in item.field_choices %}
<option value="{{ value }}" {% if clause.field == value %}selected{% endif %}>{{ label }}</option>
<option value="{{ value }}" {% if first_clause.field == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</label>
<label class="field-rule-control">
<label class="conditional-clause-control conditional-clause-operator">
<span>{% trans "Operator" %}</span>
<select name="conditional_operator_{{ item.target_key }}_{{ forloop.counter0 }}">
<select name="conditional_operator_{{ item.target_key }}_0">
{% for value, label in item.operator_choices %}
<option value="{{ value }}" {% if clause.operator == value %}selected{% endif %}>{{ label }}</option>
<option value="{{ value }}" {% if first_clause.operator == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</label>
<label class="field-rule-control">
<label class="conditional-clause-control conditional-clause-value">
<span>{% trans "Wert" %}</span>
<input type="text" name="conditional_value_{{ item.target_key }}_{{ forloop.counter0 }}" value="{{ clause.value }}" {% if clause.operator == 'checked' %}placeholder="{% trans 'wird ignoriert' %}"{% endif %} />
<input type="text" name="conditional_value_{{ item.target_key }}_0" value="{{ first_clause.value }}" {% if first_clause.operator == 'checked' %}placeholder="{% trans 'wird ignoriert' %}"{% endif %} />
</label>
</div>
{% endfor %}
<details class="conditional-extra-clause" {% if second_clause.field %}open{% endif %}>
<summary>{% trans "Zusätzliche Bedingung" %}</summary>
<div class="conditional-clause-row conditional-clause-row-secondary">
<div class="conditional-clause-index">
{% trans "Und" %}
</div>
<label class="conditional-clause-control conditional-clause-field">
<span>{% trans "Feld" %}</span>
<select name="conditional_field_{{ item.target_key }}_1">
<option value="">{% trans "Keine" %}</option>
{% for value, label in item.field_choices %}
<option value="{{ value }}" {% if second_clause.field == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</label>
<label class="conditional-clause-control conditional-clause-operator">
<span>{% trans "Operator" %}</span>
<select name="conditional_operator_{{ item.target_key }}_1">
{% for value, label in item.operator_choices %}
<option value="{{ value }}" {% if second_clause.operator == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</label>
<label class="conditional-clause-control conditional-clause-value">
<span>{% trans "Wert" %}</span>
<input type="text" name="conditional_value_{{ item.target_key }}_1" value="{{ second_clause.value }}" {% if second_clause.operator == 'checked' %}placeholder="{% trans 'wird ignoriert' %}"{% endif %} />
</label>
</div>
</details>
{% endwith %}
</div>
</section>
{% endfor %}
@@ -313,7 +298,8 @@
<button class="btn btn-primary" type="submit" name="builder_action" value="save_conditional_rules">{% trans "Bedingte Logik speichern" %}</button>
</div>
</form>
</section>
</div>
</details>
{% endif %}
</div>
</div>
@@ -457,6 +443,86 @@
</div>
</details>
{% if form_type == 'onboarding' %}
<details class="options-panel nested-accordion js-single-accordion" data-accordion-group="builder-content-subpanels" {% if active_subpanel == 'custom-sections' %}open{% endif %}>
<summary class="nested-accordion-summary">
<div class="options-head">
<h2>{% trans "Eigene Abschnitte" %}</h2>
<span class="builder-panel-toggle">{% trans "Öffnen" %}</span>
</div>
</summary>
<div class="nested-accordion-body">
<form class="builder-entity-form" method="post" action="/admin-tools/form-builder/?form_type={{ form_type }}&option_category={{ selected_option_category }}">
{% csrf_token %}
<input type="hidden" name="builder_action" value="add_custom_section" />
<div class="builder-entity-head">
<div>
<h3>{% trans "Abschnitt hinzufügen" %}</h3>
<p class="mini">{% trans "Erstellen Sie zusätzliche Bereiche für deployment-spezifische Informationen." %}</p>
</div>
</div>
<div class="builder-entity-grid">
<label class="builder-entity-control">
<span>{% trans "Titel (DE)" %}</span>
<input type="text" name="custom_section_title" required />
</label>
<label class="builder-entity-control">
<span>{% trans "Titel (EN)" %}</span>
<input type="text" name="custom_section_title_en" />
</label>
<label class="builder-entity-control builder-entity-control-narrow">
<span>{% trans "Sortierung" %}</span>
<input type="number" name="custom_section_sort_order" min="0" value="0" />
</label>
</div>
<div class="options-actions">
<button class="btn btn-primary" type="submit">{% trans "Abschnitt hinzufügen" %}</button>
</div>
</form>
<form method="post" action="/admin-tools/form-builder/?form_type={{ form_type }}&option_category={{ selected_option_category }}">
{% csrf_token %}
<div class="builder-card-list">
{% for item in custom_section_items %}
<article class="builder-entity-card">
<input type="hidden" name="custom_section_ids" value="{{ item.id }}" />
<div class="builder-entity-card-head">
<div>
<strong>{{ item.title }}</strong>
<div class="entity-meta">{{ item.section_key }}</div>
</div>
<label class="builder-switch">
<input type="checkbox" name="custom_section_is_active_{{ item.id }}" {% if item.is_active %}checked{% endif %} />
<span>{% trans "Aktiv" %}</span>
</label>
</div>
<div class="builder-entity-grid">
<label class="builder-entity-control">
<span>{% trans "Titel (DE)" %}</span>
<input type="text" name="custom_section_title_{{ item.id }}" value="{{ item.title }}" required />
</label>
<label class="builder-entity-control">
<span>{% trans "Titel (EN)" %}</span>
<input type="text" name="custom_section_title_en_{{ item.id }}" value="{{ item.title_en }}" />
</label>
<label class="builder-entity-control builder-entity-control-narrow">
<span>{% trans "Sortierung" %}</span>
<input type="number" min="0" name="custom_section_sort_order_{{ item.id }}" value="{{ item.sort_order }}" />
</label>
</div>
</article>
{% empty %}
<div class="builder-empty-state">{% trans "Keine eigenen Abschnitte vorhanden." %}</div>
{% endfor %}
</div>
<div class="options-actions">
<button class="btn btn-primary" type="submit" name="builder_action" value="save_custom_sections">{% trans "Abschnitte speichern" %}</button>
</div>
</form>
</div>
</details>
{% endif %}
<details class="options-panel nested-accordion js-single-accordion" data-accordion-group="builder-content-subpanels" {% if active_subpanel == 'custom-fields' %}open{% endif %}>
<summary class="nested-accordion-summary">
<div class="options-head">
@@ -465,98 +531,155 @@
</div>
</summary>
<div class="nested-accordion-body">
<form class="add-option-form" method="post" action="/admin-tools/form-builder/?form_type={{ form_type }}&option_category={{ selected_option_category }}">
<form class="builder-entity-form" method="post" action="/admin-tools/form-builder/?form_type={{ form_type }}&option_category={{ selected_option_category }}">
{% csrf_token %}
<input type="hidden" name="builder_action" value="add_custom_field" />
<input type="text" name="custom_label" placeholder="{% trans 'Label (DE)' %}" required />
<input type="text" name="custom_label_en" placeholder="{% trans 'Label (EN, optional)' %}" />
<select name="custom_section_key">
{% for group in custom_field_groups %}
<option value="{{ group.key }}">{{ group.title }}</option>
{% endfor %}
</select>
<select name="custom_field_type">
{% for value, label in custom_field_type_choices %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
</select>
<input type="number" name="custom_sort_order" min="0" value="0" placeholder="{% trans 'Sortierung' %}" />
<label class="field-rule-control compact-inline">
<span>{% trans "Pflicht" %}</span>
<input type="checkbox" name="custom_is_required" />
</label>
<input type="text" name="custom_help_text" placeholder="{% trans 'Hilfetext (DE, optional)' %}" />
<input type="text" name="custom_help_text_en" placeholder="{% trans 'Hilfetext (EN, optional)' %}" />
<textarea name="custom_select_options" rows="3" placeholder="{% trans 'Optionen (eine pro Zeile, optional: wert|Label)' %}"></textarea>
<textarea name="custom_select_options_en" rows="3" placeholder="{% trans 'Optionen EN (eine pro Zeile, optional: value|Label)' %}"></textarea>
<button class="btn btn-primary" type="submit">{% trans "Eigenes Feld hinzufügen" %}</button>
<div class="builder-entity-head">
<div>
<h3>{% trans "Feld hinzufügen" %}</h3>
<p class="mini">{% trans "Erstellen Sie zusätzliche Eingaben innerhalb eines bestehenden oder eigenen Abschnitts." %}</p>
</div>
</div>
<div class="builder-entity-grid">
<label class="builder-entity-control">
<span>{% trans "Label (DE)" %}</span>
<input type="text" name="custom_label" required />
</label>
<label class="builder-entity-control">
<span>{% trans "Label (EN)" %}</span>
<input type="text" name="custom_label_en" />
</label>
<label class="builder-entity-control">
<span>{% trans "Abschnitt" %}</span>
<select name="custom_section_key">
{% for group in custom_field_groups %}
<option value="{{ group.key }}">{{ group.title }}</option>
{% endfor %}
</select>
</label>
<label class="builder-entity-control">
<span>{% trans "Typ" %}</span>
<select name="custom_field_type">
{% for value, label in custom_field_type_choices %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
</select>
</label>
<label class="builder-entity-control builder-entity-control-narrow">
<span>{% trans "Sortierung" %}</span>
<input type="number" name="custom_sort_order" min="0" value="0" />
</label>
<label class="builder-switch builder-switch-inline">
<input type="checkbox" name="custom_is_required" />
<span>{% trans "Pflichtfeld" %}</span>
</label>
<label class="builder-entity-control">
<span>{% trans "Hilfetext (DE)" %}</span>
<input type="text" name="custom_help_text" />
</label>
<label class="builder-entity-control">
<span>{% trans "Hilfetext (EN)" %}</span>
<input type="text" name="custom_help_text_en" />
</label>
<label class="builder-entity-control builder-entity-control-full">
<span>{% trans "Optionen (DE)" %}</span>
<textarea name="custom_select_options" rows="3" placeholder="{% trans 'Eine Option pro Zeile, optional: wert|Label' %}"></textarea>
</label>
<label class="builder-entity-control builder-entity-control-full">
<span>{% trans "Optionen (EN)" %}</span>
<textarea name="custom_select_options_en" rows="3" placeholder="{% trans 'Eine Option pro Zeile, optional: value|Label' %}"></textarea>
</label>
</div>
<div class="options-actions">
<button class="btn btn-primary" type="submit">{% trans "Eigenes Feld hinzufügen" %}</button>
</div>
</form>
<form method="post" action="/admin-tools/form-builder/?form_type={{ form_type }}&option_category={{ selected_option_category }}">
{% csrf_token %}
<div class="option-table-wrap">
<table class="option-table">
<thead>
<tr>
<th>{% trans "Schlüssel" %}</th>
<th>{% trans "Abschnitt" %}</th>
<th>{% trans "Typ" %}</th>
<th>{% trans "Sortierung" %}</th>
<th>{% trans "Label (DE)" %}</th>
<th>{% trans "Label (EN)" %}</th>
<th>{% trans "Pflicht" %}</th>
<th>{% trans "Aktiv" %}</th>
<th>{% trans "Löschen" %}</th>
</tr>
</thead>
<tbody>
{% for group in custom_field_groups %}
<tr class="option-table-group-row">
<th colspan="9">{{ group.title }}</th>
</tr>
<div class="builder-group-stack">
{% for group in custom_field_groups %}
<section class="builder-group-card">
<div class="builder-group-head">
<h3>{{ group.title }}</h3>
<span class="column-count">{% blocktrans trimmed with count=group.items|length %}{{ count }} Feld/Felder{% endblocktrans %}</span>
</div>
<div class="builder-card-list">
{% for item in group.items %}
<tr>
<td>
<input type="hidden" name="custom_field_ids" value="{{ item.id }}" />
<strong>{{ item.field_key }}</strong>
</td>
<td>
<select name="custom_section_key_{{ item.id }}">
{% for group_choice in custom_field_groups %}
<option value="{{ group_choice.key }}" {% if group_choice.key == item.section_key %}selected{% endif %}>{{ group_choice.title }}</option>
{% endfor %}
</select>
</td>
<td>
<select name="custom_field_type_{{ item.id }}">
{% for value, label in custom_field_type_choices %}
<option value="{{ value }}" {% if value == item.field_type %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</td>
<td><input type="number" min="0" name="custom_sort_order_{{ item.id }}" value="{{ item.sort_order }}" /></td>
<td>
<input type="text" name="custom_label_{{ item.id }}" value="{{ item.label }}" required />
<input type="text" name="custom_help_text_{{ item.id }}" value="{{ item.help_text }}" placeholder="{% trans 'Hilfetext (DE)' %}" />
<textarea name="custom_select_options_{{ item.id }}" rows="2" placeholder="{% trans 'Optionen (DE)' %}">{{ item.select_options }}</textarea>
</td>
<td>
<input type="text" name="custom_label_en_{{ item.id }}" value="{{ item.label_en }}" />
<input type="text" name="custom_help_text_en_{{ item.id }}" value="{{ item.help_text_en }}" placeholder="{% trans 'Hilfetext (EN)' %}" />
<textarea name="custom_select_options_en_{{ item.id }}" rows="2" placeholder="{% trans 'Optionen (EN)' %}">{{ item.select_options_en }}</textarea>
</td>
<td><input type="checkbox" name="custom_is_required_{{ item.id }}" {% if item.is_required %}checked{% endif %} /></td>
<td><input type="checkbox" name="custom_is_active_{{ item.id }}" {% if item.is_active %}checked{% endif %} /></td>
<td>
<article class="builder-entity-card">
<input type="hidden" name="custom_field_ids" value="{{ item.id }}" />
<div class="builder-entity-card-head">
<div>
<strong>{{ item.label }}</strong>
<div class="entity-meta">{{ item.field_key }}</div>
</div>
<div class="builder-switch-stack">
<label class="builder-switch">
<input type="checkbox" name="custom_is_required_{{ item.id }}" {% if item.is_required %}checked{% endif %} />
<span>{% trans "Pflicht" %}</span>
</label>
<label class="builder-switch">
<input type="checkbox" name="custom_is_active_{{ item.id }}" {% if item.is_active %}checked{% endif %} />
<span>{% trans "Aktiv" %}</span>
</label>
</div>
</div>
<div class="builder-entity-grid">
<label class="builder-entity-control">
<span>{% trans "Abschnitt" %}</span>
<select name="custom_section_key_{{ item.id }}">
{% for group_choice in custom_field_groups %}
<option value="{{ group_choice.key }}" {% if group_choice.key == item.section_key %}selected{% endif %}>{{ group_choice.title }}</option>
{% endfor %}
</select>
</label>
<label class="builder-entity-control">
<span>{% trans "Typ" %}</span>
<select name="custom_field_type_{{ item.id }}">
{% for value, label in custom_field_type_choices %}
<option value="{{ value }}" {% if value == item.field_type %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</label>
<label class="builder-entity-control builder-entity-control-narrow">
<span>{% trans "Sortierung" %}</span>
<input type="number" min="0" name="custom_sort_order_{{ item.id }}" value="{{ item.sort_order }}" />
</label>
<label class="builder-entity-control">
<span>{% trans "Label (DE)" %}</span>
<input type="text" name="custom_label_{{ item.id }}" value="{{ item.label }}" required />
</label>
<label class="builder-entity-control">
<span>{% trans "Label (EN)" %}</span>
<input type="text" name="custom_label_en_{{ item.id }}" value="{{ item.label_en }}" />
</label>
<label class="builder-entity-control">
<span>{% trans "Hilfetext (DE)" %}</span>
<input type="text" name="custom_help_text_{{ item.id }}" value="{{ item.help_text }}" />
</label>
<label class="builder-entity-control">
<span>{% trans "Hilfetext (EN)" %}</span>
<input type="text" name="custom_help_text_en_{{ item.id }}" value="{{ item.help_text_en }}" />
</label>
<label class="builder-entity-control builder-entity-control-full">
<span>{% trans "Optionen (DE)" %}</span>
<textarea name="custom_select_options_{{ item.id }}" rows="2">{{ item.select_options }}</textarea>
</label>
<label class="builder-entity-control builder-entity-control-full">
<span>{% trans "Optionen (EN)" %}</span>
<textarea name="custom_select_options_en_{{ item.id }}" rows="2">{{ item.select_options_en }}</textarea>
</label>
</div>
<div class="builder-entity-card-actions">
<button class="btn btn-secondary" type="submit" name="delete_custom_field_id" value="{{ item.id }}" data-confirm="{% trans 'Eigenes Feld wirklich löschen?' %}">{% trans "Löschen" %}</button>
</td>
</tr>
</div>
</article>
{% empty %}
<tr><td colspan="9">{% trans "Keine eigenen Felder vorhanden." %}</td></tr>
<div class="builder-empty-state">{% trans "Keine eigenen Felder vorhanden." %}</div>
{% endfor %}
{% endfor %}
</tbody>
</table>
</div>
</section>
{% endfor %}
</div>
<div class="options-actions">
<button class="btn btn-primary" type="submit" name="builder_action" value="save_custom_fields">{% trans "Eigene Felder speichern" %}</button>
@@ -564,6 +687,34 @@
</form>
</div>
</details>
<details class="options-panel nested-accordion js-single-accordion" data-accordion-group="builder-content-subpanels" {% if active_subpanel == 'preview' %}open{% endif %}>
<summary class="nested-accordion-summary">
<div class="options-head">
<h2>{% trans "Live-Vorschau" %}</h2>
<span class="builder-panel-toggle">{% trans "Öffnen" %}</span>
</div>
</summary>
<div class="nested-accordion-body">
<div class="preview-shell preview-shell-compact">
{% for section in preview_sections %}
<section class="preview-section">
<div class="preview-section-head">
<h3>{{ section.title }}</h3>
<span class="column-count">{% blocktrans trimmed with count=section.items|length %}{{ count }} Feld/Felder{% endblocktrans %}</span>
</div>
<div class="preview-chip-list">
{% for item in section.items %}
<span class="preview-chip{% if item.locked %} is-locked{% endif %}">{{ item.label }}</span>
{% empty %}
<span class="mini">{% trans "Keine sichtbaren Felder." %}</span>
{% endfor %}
</div>
</section>
{% endfor %}
</div>
</div>
</details>
</div>
</div>
</details>

View File

@@ -59,13 +59,7 @@
{% with field=block.field %}
{% if field.is_hidden %}
{{ field }}
{% elif field.name in onboarding_inline_checks or field.field.widget.input_type == 'checkbox' %}
<div class="field inline-check field-full {% if section.key == 'abschluss' %}finish-check{% endif %}">
{{ field }} {{ field.label_tag }}
{% if field.help_text %}<div class="hint">{{ field.help_text }}</div>{% endif %}
{{ field.errors }}
</div>
{% elif section.key == 'itsetup' and field.name in onboarding_checkbox_lists %}
{% elif field.name in onboarding_checkbox_lists %}
<div class="itsetup-checklist-panel field-full">
<div class="itsetup-checklist-head">
<h3>{{ field.label }}</h3>
@@ -83,8 +77,14 @@
{{ field.errors }}
</div>
</div>
{% elif field.name in onboarding_inline_checks or field.field.widget.input_type == 'checkbox' %}
<div class="field inline-check field-full {% if section.key == 'abschluss' %}finish-check{% endif %}">
{{ field }} {{ field.label_tag }}
{% if field.help_text %}<div class="hint">{{ field.help_text }}</div>{% endif %}
{{ field.errors }}
</div>
{% else %}
<div class="field {% if section.key == 'abschluss' %}finish-field{% endif %} {% if field.name in onboarding_checkbox_lists or field.name == 'gender' or field.name == 'additional_hardware_needed_choice' or field.name == 'additional_software_needed_choice' or field.name == 'additional_access_needed_choice' or field.name == 'successor_required_choice' %}field-full{% endif %} {% if field.name in onboarding_checkbox_lists %}checkbox-list{% endif %} {% if section.key == 'itsetup' and field.name in onboarding_checkbox_lists %}itsetup-checklist-block{% endif %}">
<div class="field {% if section.key == 'abschluss' %}finish-field{% endif %} {% if field.name in onboarding_checkbox_lists or field.name == 'gender' or field.name == 'additional_hardware_needed_choice' or field.name == 'additional_software_needed_choice' or field.name == 'additional_access_needed_choice' or field.name == 'successor_required_choice' %}field-full{% endif %} {% if field.name in onboarding_checkbox_lists %}checkbox-list itsetup-checklist-block{% endif %}">
{{ field.label_tag }}
{{ field }}
{% if field.help_text %}<div class="hint">{{ field.help_text }}</div>{% endif %}
@@ -102,13 +102,7 @@
{% for field in block.fields %}
{% if field.is_hidden %}
{{ field }}
{% elif field.name in onboarding_inline_checks or field.field.widget.input_type == 'checkbox' %}
<div class="field inline-check field-full {% if section.key == 'abschluss' %}finish-check{% endif %}">
{{ field }} {{ field.label_tag }}
{% if field.help_text %}<div class="hint">{{ field.help_text }}</div>{% endif %}
{{ field.errors }}
</div>
{% elif section.key == 'itsetup' and field.name in onboarding_checkbox_lists %}
{% elif field.name in onboarding_checkbox_lists %}
<div class="itsetup-checklist-panel field-full">
<div class="itsetup-checklist-head">
<h3>{{ field.label }}</h3>
@@ -126,8 +120,14 @@
{{ field.errors }}
</div>
</div>
{% elif field.name in onboarding_inline_checks or field.field.widget.input_type == 'checkbox' %}
<div class="field inline-check field-full {% if section.key == 'abschluss' %}finish-check{% endif %}">
{{ field }} {{ field.label_tag }}
{% if field.help_text %}<div class="hint">{{ field.help_text }}</div>{% endif %}
{{ field.errors }}
</div>
{% else %}
<div class="field {% if section.key == 'abschluss' %}finish-field{% endif %} {% if field.name in onboarding_checkbox_lists or field.name == 'gender' or field.name == 'additional_hardware_needed_choice' or field.name == 'additional_software_needed_choice' or field.name == 'additional_access_needed_choice' or field.name == 'successor_required_choice' %}field-full{% endif %} {% if field.name in onboarding_checkbox_lists %}checkbox-list{% endif %} {% if section.key == 'itsetup' and field.name in onboarding_checkbox_lists %}itsetup-checklist-block{% endif %}">
<div class="field {% if section.key == 'abschluss' %}finish-field{% endif %} {% if field.name in onboarding_checkbox_lists or field.name == 'gender' or field.name == 'additional_hardware_needed_choice' or field.name == 'additional_software_needed_choice' or field.name == 'additional_access_needed_choice' or field.name == 'successor_required_choice' %}field-full{% endif %} {% if field.name in onboarding_checkbox_lists %}checkbox-list itsetup-checklist-block{% endif %}">
{{ field.label_tag }}
{{ field }}
{% if field.help_text %}<div class="hint">{{ field.help_text }}</div>{% endif %}