refine form builder workspace interactions

This commit is contained in:
Md Bayazid Bostame
2026-03-27 21:06:03 +01:00
parent b0cc5bda78
commit 61e3fae18d
3 changed files with 1290 additions and 432 deletions

View File

@@ -2189,6 +2189,13 @@ def form_builder_page(request):
active_panel = (request.GET.get('panel') or '').strip()
active_subpanel = (request.GET.get('subpanel') or '').strip()
active_rules_panel = (request.GET.get('rules_panel') or '').strip()
active_module = (request.GET.get('module') or '').strip()
active_structure_section = (request.GET.get('structure_section') or '').strip()
active_field_rules_section = ((request.POST.get('field_rules_section') if request.method == 'POST' else '') or request.GET.get('field_rules_section') or '').strip()
active_field_texts_section = ((request.POST.get('field_texts_section') if request.method == 'POST' else '') or request.GET.get('field_texts_section') or '').strip()
active_custom_fields_section = ((request.POST.get('custom_fields_section') if request.method == 'POST' else '') or request.GET.get('custom_fields_section') or '').strip()
active_section_rules_section = ((request.POST.get('section_rules_section') if request.method == 'POST' else '') or request.GET.get('section_rules_section') or '').strip()
active_conditional_target = ((request.POST.get('conditional_target') if request.method == 'POST' else '') or request.GET.get('conditional_target') or '').strip()
if form_type not in DEFAULT_FIELD_ORDER:
form_type = 'onboarding'
option_category = request.GET.get('option_category', 'department')
@@ -2196,6 +2203,34 @@ def form_builder_page(request):
if option_category not in option_categories:
option_category = option_categories[0]
valid_modules = {
'structure',
'section-rules',
'field-rules',
'conditional-rules',
'options',
'field-texts',
'custom-sections',
'custom-fields',
'preview',
}
if not active_module:
if active_panel == 'builder-structure':
active_module = 'structure'
elif active_panel == 'builder-rules':
active_module = active_rules_panel or 'section-rules'
elif active_panel == 'builder-content':
active_module = active_subpanel or 'options'
else:
active_module = 'structure'
if active_module not in valid_modules:
active_module = 'structure'
if form_type != 'onboarding' and active_module == 'custom-sections':
active_module = 'options'
if form_type != 'onboarding' and active_module == 'conditional-rules':
active_module = 'field-rules'
if request.method == 'POST':
delete_option_id = request.POST.get('delete_option_id', '').strip()
delete_custom_field_id = request.POST.get('delete_custom_field_id', '').strip()
@@ -2211,7 +2246,7 @@ def form_builder_page(request):
option.delete()
_audit(request, 'form_option_deleted', target_type='form_option', target_id=deleted_id, target_label=deleted_label)
messages.success(request, 'Option wurde gelöscht.')
return redirect(f"/admin-tools/form-builder/?form_type={form_type}&option_category={option_category}&panel=builder-content&subpanel=options#builder-content")
return redirect(f"/admin-tools/form-builder/?form_type={form_type}&option_category={option_category}&module=options")
if delete_custom_field_id:
custom_field = FormCustomFieldConfig.objects.filter(id=delete_custom_field_id, form_type=form_type).first()
if not custom_field:
@@ -2222,7 +2257,7 @@ def form_builder_page(request):
custom_field.delete()
_audit(request, 'form_custom_field_deleted', target_type='form_custom_field', target_id=deleted_id, target_label=deleted_label)
messages.success(request, 'Benutzerdefiniertes Feld wurde gelöscht.')
return redirect(f"/admin-tools/form-builder/?form_type={form_type}&option_category={option_category}&panel=builder-content&subpanel=custom-fields#builder-content")
return redirect(f"/admin-tools/form-builder/?form_type={form_type}&option_category={option_category}&module=custom-fields")
if delete_custom_section_id:
custom_section = FormCustomSectionConfig.objects.filter(id=delete_custom_section_id, form_type=form_type).first()
if not custom_section:
@@ -2250,7 +2285,7 @@ def form_builder_page(request):
details={'section_key': section_key, 'deleted_field_count': deleted_field_count},
)
messages.success(request, 'Benutzerdefinierter Abschnitt wurde gelöscht.')
return redirect(f"/admin-tools/form-builder/?form_type={form_type}&option_category={option_category}&panel=builder-content&subpanel=custom-sections#builder-content")
return redirect(f"/admin-tools/form-builder/?form_type={form_type}&option_category={option_category}&module=custom-sections")
action = request.POST.get('builder_action', '')
if action == 'add_option':
@@ -2301,7 +2336,7 @@ def form_builder_page(request):
option.save(update_fields=['label', 'label_en', 'value', 'is_active', 'sort_order'])
except IntegrityError:
messages.error(request, f'Doppelte Bezeichnung in Kategorie: {next_label}')
return redirect(f"/admin-tools/form-builder/?form_type={form_type}&option_category={option.category}&panel=builder-content&subpanel=options#builder-content")
return redirect(f"/admin-tools/form-builder/?form_type={form_type}&option_category={option.category}&module=options")
option_category = option.category
_audit(request, 'form_options_saved', target_type='form_option', target_label=option_category, details={'count': len(option_ids)})
messages.success(request, 'Optionen wurden gespeichert.')
@@ -2447,7 +2482,7 @@ def form_builder_page(request):
cfg.select_options_en = (request.POST.get(f'custom_select_options_en_{cfg.id}') or '').strip()
if cfg.field_type == FormCustomFieldConfig.FIELD_TYPE_SELECT and not cfg.select_options:
messages.error(request, f'Auswahlfeld "{cfg.label}" benötigt mindestens eine Option.')
return redirect(f"/admin-tools/form-builder/?form_type={form_type}&option_category={option_category}&panel=builder-content&subpanel=custom-fields#builder-content")
return redirect(f"/admin-tools/form-builder/?form_type={form_type}&option_category={option_category}&module=custom-fields")
cfg.save()
updated += 1
_audit(request, 'form_custom_fields_saved', target_type='form_custom_field', target_label=form_type, details={'count': updated})
@@ -2536,40 +2571,43 @@ def form_builder_page(request):
elif action == 'apply_preset':
preset_key = (request.POST.get('preset_key') or '').strip()
if apply_form_preset(form_type, preset_key):
active_panel = 'builder-content'
active_subpanel = 'preview'
active_module = 'preview'
_audit(request, 'form_preset_applied', target_type='form_config', target_label=form_type, details={'preset': preset_key})
messages.success(request, 'Preset wurde angewendet.')
else:
messages.error(request, 'Preset konnte nicht angewendet werden.')
if action in {'add_option', 'save_options', 'save_field_texts', 'add_custom_field', 'save_custom_fields', 'add_custom_section', 'save_custom_sections'}:
active_panel = 'builder-content'
if action in {'add_option', 'save_options'}:
active_subpanel = 'options'
active_module = 'options'
elif action == 'save_field_texts':
active_subpanel = 'field-texts'
active_module = 'field-texts'
elif action in {'add_custom_field', 'save_custom_fields'}:
active_subpanel = 'custom-fields'
active_module = 'custom-fields'
elif action in {'add_custom_section', 'save_custom_sections'}:
active_subpanel = 'custom-sections'
active_module = 'custom-sections'
elif action in {'save_field_rules', 'save_section_rules', 'save_conditional_rules'}:
active_panel = 'builder-rules'
active_module = 'section-rules'
if action == 'save_section_rules':
active_rules_panel = 'section-rules'
active_module = 'section-rules'
elif action == 'save_field_rules':
active_rules_panel = 'field-rules'
active_module = 'field-rules'
elif action == 'save_conditional_rules':
active_rules_panel = 'conditional-rules'
active_module = 'conditional-rules'
redirect_target = f"/admin-tools/form-builder/?form_type={form_type}&option_category={option_category}"
if active_panel:
redirect_target += f"&panel={active_panel}"
if active_subpanel:
redirect_target += f"&subpanel={active_subpanel}"
if active_rules_panel:
redirect_target += f"&rules_panel={active_rules_panel}"
if anchor == 'builder-content' or active_panel == 'builder-content':
redirect_target += "#builder-content"
if active_module:
redirect_target += f"&module={active_module}"
if active_structure_section:
redirect_target += f"&structure_section={active_structure_section}"
if active_section_rules_section and active_module == 'section-rules':
redirect_target += f"&section_rules_section={active_section_rules_section}"
if active_field_rules_section and active_module == 'field-rules':
redirect_target += f"&field_rules_section={active_field_rules_section}"
if active_conditional_target and active_module == 'conditional-rules':
redirect_target += f"&conditional_target={active_conditional_target}"
if active_field_texts_section and active_module == 'field-texts':
redirect_target += f"&field_texts_section={active_field_texts_section}"
if active_custom_fields_section and active_module == 'custom-fields':
redirect_target += f"&custom_fields_section={active_custom_fields_section}"
return redirect(redirect_target)
default_names = list(DEFAULT_FIELD_ORDER.get(form_type, []))
@@ -2700,6 +2738,8 @@ def form_builder_page(request):
section_rule_items = []
if section_order:
if active_structure_section not in section_order:
active_structure_section = section_order[0]
fallback_section = section_order[-1] if section_order else ''
custom_section_map = {cfg.section_key: cfg for cfg in custom_section_configs}
for key in section_order:
@@ -2717,6 +2757,9 @@ def form_builder_page(request):
'field_count': len([c for c in configs if (c.page_key or default_page_map.get(c.field_name, fallback_section)) == key]) + len([c for c in custom_field_configs if c.section_key == key]),
}
)
section_rule_keys = [item['key'] for item in section_rule_items]
if section_rule_keys and active_section_rules_section not in section_rule_keys:
active_section_rules_section = section_rule_keys[0]
field_rule_items = []
for cfg in configs:
@@ -2747,6 +2790,11 @@ def form_builder_page(request):
'items': grouped_custom.get(key, []),
}
)
custom_section_field_counts: dict[str, int] = {}
for cfg in custom_field_configs:
custom_section_field_counts[cfg.section_key] = custom_section_field_counts.get(cfg.section_key, 0) + 1
for cfg in custom_section_configs:
cfg.custom_field_count = custom_section_field_counts.get(cfg.section_key, 0)
field_rule_groups = []
if section_order:
@@ -2761,6 +2809,9 @@ def form_builder_page(request):
'items': grouped_rules.get(key, []),
}
)
field_rule_group_keys = [group['key'] for group in field_rule_groups]
if field_rule_group_keys and active_field_rules_section not in field_rule_group_keys:
active_field_rules_section = field_rule_group_keys[0]
field_text_groups = []
if section_order:
@@ -2776,6 +2827,12 @@ def form_builder_page(request):
'items': grouped_texts.get(key, []),
}
)
field_text_group_keys = [group['key'] for group in field_text_groups]
if field_text_group_keys and active_field_texts_section not in field_text_group_keys:
active_field_texts_section = field_text_group_keys[0]
custom_field_group_keys = [group['key'] for group in custom_field_groups]
if custom_field_group_keys and active_custom_fields_section not in custom_field_group_keys:
active_custom_fields_section = custom_field_group_keys[0]
conditional_rule_items = []
if form_type == 'onboarding':
@@ -2837,6 +2894,9 @@ def form_builder_page(request):
'target_fields': target_fields,
}
)
conditional_rule_keys = [item['target_key'] for item in conditional_rule_items]
if conditional_rule_keys and active_conditional_target not in conditional_rule_keys:
active_conditional_target = conditional_rule_keys[0]
preview_sections = []
if section_order:
@@ -2906,6 +2966,13 @@ def form_builder_page(request):
'active_panel': active_panel,
'active_subpanel': active_subpanel,
'active_rules_panel': active_rules_panel,
'active_module': active_module,
'active_structure_section': active_structure_section,
'active_field_rules_section': active_field_rules_section,
'active_field_texts_section': active_field_texts_section,
'active_custom_fields_section': active_custom_fields_section,
'active_section_rules_section': active_section_rules_section,
'active_conditional_target': active_conditional_target,
'available_presets': FORM_PRESETS.get(form_type, {}),
'can_override_locked_builder_rules': can_override_locked_builder_rules,
},