Skip to content

Commit e3405b8

Browse files
committed
feat: Fix visual editors and add approval_step support to form builder
Workflow Visual Editor: - Fixed handling of legacy visual_workflow_data format (stages array) - Now regenerates visual layout when old format is detected Form Visual Editor: - Added approval_step field to form_builder_load API - Added approval_step field to form_builder_save API - Added Approval Step dropdown in field properties UI - Allows assigning fields to approval steps 1-4 for sequential workflows Bump version to 0.7.5
1 parent 96f8820 commit e3405b8

5 files changed

Lines changed: 39 additions & 6 deletions

File tree

django_forms_workflows/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Enterprise-grade, database-driven form builder with approval workflows
44
"""
55

6-
__version__ = "0.7.4"
6+
__version__ = "0.7.5"
77
__author__ = "Django Forms Workflows Contributors"
88
__license__ = "LGPL-3.0-only"
99

django_forms_workflows/form_builder_views.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ def form_builder_load(request, form_id):
230230
"show_if_field": field.show_if_field,
231231
"show_if_value": field.show_if_value or "",
232232
},
233+
"approval_step": field.approval_step,
233234
}
234235
fields_data.append(field_data)
235236

@@ -391,6 +392,15 @@ def form_builder_save(request):
391392
}
392393
)
393394

395+
# Add approval step (for sequential approval workflows)
396+
approval_step = field_data.get("approval_step")
397+
if approval_step is not None:
398+
field_props["approval_step"] = (
399+
int(approval_step) if approval_step else None
400+
)
401+
else:
402+
field_props["approval_step"] = None
403+
394404
# Create or update field
395405
if field_id and isinstance(field_id, int):
396406
# Update existing field

django_forms_workflows/static/django_forms_workflows/js/form-builder.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,17 @@ class FormBuilder {
594594
<label class="form-label">CSS Class</label>
595595
<input type="text" class="form-control" id="propCssClass" value="${this.escapeHtml(field.css_class)}">
596596
</div>
597+
<div class="col-12">
598+
<label class="form-label">Approval Step</label>
599+
<select class="form-select" id="propApprovalStep">
600+
<option value="" ${!field.approval_step ? 'selected' : ''}>None (Student-facing)</option>
601+
<option value="1" ${field.approval_step === 1 ? 'selected' : ''}>Step 1</option>
602+
<option value="2" ${field.approval_step === 2 ? 'selected' : ''}>Step 2</option>
603+
<option value="3" ${field.approval_step === 3 ? 'selected' : ''}>Step 3</option>
604+
<option value="4" ${field.approval_step === 4 ? 'selected' : ''}>Step 4</option>
605+
</select>
606+
<small class="text-muted">Assign to an approval step for sequential approval workflows</small>
607+
</div>
597608
</div>
598609
`;
599610
}
@@ -1387,6 +1398,10 @@ class FormBuilder {
13871398
const prefillSelect = document.getElementById('propPrefillSource');
13881399
field.prefill_source_id = prefillSelect.value ? parseInt(prefillSelect.value) : null;
13891400

1401+
// Save approval step
1402+
const approvalStepSelect = document.getElementById('propApprovalStep');
1403+
field.approval_step = approvalStepSelect.value ? parseInt(approvalStepSelect.value) : null;
1404+
13901405
const choicesEl = document.getElementById('propChoices');
13911406
if (choicesEl) {
13921407
field.choices = choicesEl.value;

django_forms_workflows/workflow_builder_views.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,20 @@ def convert_workflow_to_visual(workflow, form_definition):
156156
"""
157157
Convert WorkflowDefinition model to visual workflow format.
158158
"""
159-
# If visual workflow data exists, return it directly
159+
# Check if visual workflow data exists AND has the correct format (nodes array)
160160
if workflow.visual_workflow_data:
161-
logger.info("Loading saved visual workflow data")
162-
return workflow.visual_workflow_data
161+
visual_data = workflow.visual_workflow_data
162+
# Check if it has the new format with nodes array
163+
if isinstance(visual_data, dict) and "nodes" in visual_data:
164+
logger.info("Loading saved visual workflow data (new format)")
165+
return visual_data
166+
else:
167+
# Old format (e.g., stages array) - regenerate
168+
logger.info(
169+
"Found legacy visual_workflow_data format, regenerating visual layout"
170+
)
163171

164-
# Otherwise, generate default layout from workflow configuration
172+
# Generate default layout from workflow configuration
165173
logger.info("Generating default visual workflow layout")
166174
nodes = []
167175
connections = []

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "django-forms-workflows"
3-
version = "0.7.4"
3+
version = "0.7.5"
44
description = "Enterprise-grade, database-driven form builder with approval workflows and external data integration"
55
license = "LGPL-3.0-only"
66
readme = "README.md"

0 commit comments

Comments
 (0)