django-forms-workflows 0.20.2__tar.gz → 0.20.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/PKG-INFO +1 -1
  2. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/submission_detail.html +28 -27
  3. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/views.py +47 -30
  4. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/pyproject.toml +1 -1
  5. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/CHANGELOG.md +0 -0
  6. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/LICENSE +0 -0
  7. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/README.md +0 -0
  8. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/__init__.py +0 -0
  9. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/admin.py +0 -0
  10. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/apps.py +0 -0
  11. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/context_processors.py +0 -0
  12. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/data_sources/__init__.py +0 -0
  13. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/data_sources/base.py +0 -0
  14. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/data_sources/database_source.py +0 -0
  15. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/data_sources/ldap_source.py +0 -0
  16. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/data_sources/user_source.py +0 -0
  17. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/email_backends/__init__.py +0 -0
  18. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/email_backends/gmail_api.py +0 -0
  19. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/form_builder_urls.py +0 -0
  20. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/form_builder_views.py +0 -0
  21. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/forms.py +0 -0
  22. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/handlers/__init__.py +0 -0
  23. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/handlers/api_handler.py +0 -0
  24. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/handlers/base.py +0 -0
  25. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/handlers/database_handler.py +0 -0
  26. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/handlers/email_handler.py +0 -0
  27. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/handlers/executor.py +0 -0
  28. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/handlers/file_handler.py +0 -0
  29. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/handlers/ldap_handler.py +0 -0
  30. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/ldap_backend.py +0 -0
  31. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/management/commands/create_default_templates.py +0 -0
  32. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/management/commands/pull_forms.py +0 -0
  33. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/management/commands/push_forms.py +0 -0
  34. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/management/commands/seed_farm_demo.py +0 -0
  35. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/management/commands/seed_pcn_form.py +0 -0
  36. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/management/commands/seed_prefill_sources.py +0 -0
  37. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/management/commands/sync_ldap_profiles.py +0 -0
  38. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/management/commands/test_db_connection.py +0 -0
  39. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0001_initial.py +0 -0
  40. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0002_prefillsource_alter_formfield_prefill_source_and_more.py +0 -0
  41. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0003_postsubmissionaction.py +0 -0
  42. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0004_formtemplate.py +0 -0
  43. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0005_advanced_conditional_logic.py +0 -0
  44. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0006_workflowdefinition_visual_workflow_data_and_more.py +0 -0
  45. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0007_add_userprofile_ldap_enhancements.py +0 -0
  46. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0008_add_file_workflow_models.py +0 -0
  47. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0009_add_formfield_readonly.py +0 -0
  48. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0010_add_prefillsource_template_fields.py +0 -0
  49. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0011_postsubmissionaction_email_body_template_and_more.py +0 -0
  50. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0012_add_approval_step_fields.py +0 -0
  51. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0013_add_database_query_key.py +0 -0
  52. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0014_add_form_category.py +0 -0
  53. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0015_add_workflowstage_staged_approvals.py +0 -0
  54. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0016_add_pdf_generation.py +0 -0
  55. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0017_add_notification_batching.py +0 -0
  56. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0018_add_form_category_parent.py +0 -0
  57. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0019_add_ldap_group_profile.py +0 -0
  58. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0020_add_bulk_export_field.py +0 -0
  59. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0021_alter_pendingnotification_scheduled_for_and_more.py +0 -0
  60. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0022_add_bulk_pdf_export.py +0 -0
  61. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0023_add_performance_indexes.py +0 -0
  62. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0024_add_allow_resubmit.py +0 -0
  63. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0025_workflowstage_approve_label.py +0 -0
  64. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0026_alter_formfield_width.py +0 -0
  65. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0027_formsubmission_form_data_gin.py +0 -0
  66. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0028_workflowstagegroupconfig.py +0 -0
  67. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0029_formfield_workflow_stage_fk_drop_groupconfig.py +0 -0
  68. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0030_formfield_phone_type.py +0 -0
  69. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0031_sub_workflows.py +0 -0
  70. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0032_approved_pending_detached_sub_workflow.py +0 -0
  71. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0033_add_reject_parent_to_subworkflowdefinition.py +0 -0
  72. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0034_add_notificationlog.py +0 -0
  73. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0035_migrate_prefill_source_strings.py +0 -0
  74. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0036_add_workflowstage_auto_created.py +0 -0
  75. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0037_migrate_flat_workflows_to_staged.py +0 -0
  76. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0038_remove_legacy_prefill_source_and_approval_step.py +0 -0
  77. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0039_update_help_text.py +0 -0
  78. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0040_migrate_deprecated_features.py +0 -0
  79. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0041_remove_deprecated_fields.py +0 -0
  80. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0042_add_sub_workflow_section_label.py +0 -0
  81. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/0043_fix_form_data_decimal_encoding.py +0 -0
  82. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/migrations/__init__.py +0 -0
  83. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/models.py +0 -0
  84. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/signals.py +0 -0
  85. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/sso_backends.py +0 -0
  86. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/sso_urls.py +0 -0
  87. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/sso_views.py +0 -0
  88. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/static/django_forms_workflows/js/form-builder.js +0 -0
  89. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/static/django_forms_workflows/js/form-enhancements.js +0 -0
  90. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/static/django_forms_workflows/js/workflow-builder.js +0 -0
  91. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/sync_api.py +0 -0
  92. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/sync_views.py +0 -0
  93. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/tasks.py +0 -0
  94. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/admin/django_forms_workflows/form_builder.html +0 -0
  95. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/admin/django_forms_workflows/formdef_change_form.html +0 -0
  96. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/admin/django_forms_workflows/formdefinition/change_list.html +0 -0
  97. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/admin/django_forms_workflows/sync_import.html +0 -0
  98. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/admin/django_forms_workflows/sync_pull.html +0 -0
  99. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/admin/django_forms_workflows/sync_push.html +0 -0
  100. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/admin/django_forms_workflows/workflow_builder.html +0 -0
  101. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/_category_node.html +0 -0
  102. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/approval_inbox.html +0 -0
  103. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/approve.html +0 -0
  104. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/base.html +0 -0
  105. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/completed_approvals.html +0 -0
  106. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/form_categories.html +0 -0
  107. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/form_list.html +0 -0
  108. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/form_submit.html +0 -0
  109. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/my_submissions.html +0 -0
  110. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/resubmit_confirm.html +0 -0
  111. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/sso/login.html +0 -0
  112. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/sub_workflow_detail.html +0 -0
  113. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/submission_bulk_pdf.html +0 -0
  114. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/submission_pdf.html +0 -0
  115. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/django_forms_workflows/withdraw_confirm.html +0 -0
  116. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/emails/approval_notification.html +0 -0
  117. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/emails/approval_reminder.html +0 -0
  118. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/emails/approval_request.html +0 -0
  119. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/emails/email_styles.html +0 -0
  120. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/emails/escalation_notification.html +0 -0
  121. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/emails/notification_digest.html +0 -0
  122. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/emails/rejection_notification.html +0 -0
  123. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/emails/submission_notification.html +0 -0
  124. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templates/registration/login.html +0 -0
  125. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templatetags/__init__.py +0 -0
  126. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/templatetags/forms_workflows_tags.py +0 -0
  127. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/urls.py +0 -0
  128. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/utils.py +0 -0
  129. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/workflow_builder_views.py +0 -0
  130. {django_forms_workflows-0.20.2 → django_forms_workflows-0.20.4}/django_forms_workflows/workflow_engine.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-forms-workflows
3
- Version: 0.20.2
3
+ Version: 0.20.4
4
4
  Summary: Enterprise-grade, database-driven form builder with approval workflows and external data integration
5
5
  License: LGPL-3.0-only
6
6
  License-File: LICENSE
@@ -241,59 +241,60 @@
241
241
  </div>
242
242
  {% endfor %}
243
243
 
244
- {% if sub_workflow_instances_merged %}
245
- {# ---- Merged sub-workflow table ---- #}
246
- <h5 class="mb-3 mt-4"><i class="bi bi-list-check"></i> {{ sub_wf_section_label|default:"Additional Approvals" }}</h5>
247
- <div class="card mb-3 border-secondary">
244
+ {% if sub_workflow_instance_stages %}
245
+ {# ---- One table per sub-workflow instance, steps as rows ---- #}
246
+ {% for section in sub_workflow_instance_stages %}
247
+ <h5 class="mb-3 mt-4"><i class="bi bi-list-check"></i> {{ section.instance.label }}</h5>
248
+ <div class="card mb-3
249
+ {% if section.instance.status == 'rejected' %}border-danger
250
+ {% elif section.instance.status == 'approved' %}border-success
251
+ {% elif section.instance.status == 'in_progress' %}border-primary
252
+ {% else %}border-secondary{% endif %}">
248
253
  <div class="card-body p-0">
249
254
  <div class="table-responsive">
250
255
  <table class="table table-sm table-hover mb-0">
251
256
  <thead class="table-light">
252
257
  <tr>
253
- <th>#</th>
254
- <th>Label</th>
258
+ <th>Step</th>
255
259
  <th>Assigned To</th>
256
260
  <th>Status</th>
257
261
  <th>Completed By</th>
258
262
  <th>Completed At</th>
259
- <th></th>
263
+ <th>Comments</th>
260
264
  </tr>
261
265
  </thead>
262
266
  <tbody>
263
- {% for row in sub_workflow_instances_merged %}
267
+ {% for stage in section.stage_groups %}
268
+ {% for task in stage.tasks %}
264
269
  <tr>
265
- <td>{{ row.instance.index }}</td>
266
- <td>{{ row.instance.label }}</td>
270
+ <td><strong>{{ stage.name }}</strong></td>
267
271
  <td>
268
- {% if row.task %}
269
- {% if row.task.assigned_to %}
270
- {{ row.task.assigned_to.get_full_name|default:row.task.assigned_to.username }}
271
- {% elif row.task.assigned_group %}
272
- {{ row.task.assigned_group.name }}
273
- {% else %}-{% endif %}
272
+ {% if task.assigned_to %}
273
+ {{ task.assigned_to.get_full_name|default:task.assigned_to.username }}
274
+ {% elif task.assigned_group %}
275
+ {{ task.assigned_group.name }} <span class="text-muted">(Group)</span>
274
276
  {% else %}-{% endif %}
275
277
  </td>
276
278
  <td>
277
- {% if row.instance.status == 'approved' %}<span class="badge bg-success">Approved</span>
278
- {% elif row.instance.status == 'rejected' %}<span class="badge bg-danger">Rejected</span>
279
- {% elif row.instance.status == 'in_progress' %}<span class="badge bg-primary">In Progress</span>
280
- {% else %}<span class="badge bg-secondary">Pending</span>
279
+ {% if task.status == 'pending' %}<span class="badge bg-warning text-dark">Pending</span>
280
+ {% elif task.status == 'approved' %}<span class="badge bg-success">Approved</span>
281
+ {% elif task.status == 'rejected' %}<span class="badge bg-danger">Rejected</span>
282
+ {% elif task.status == 'expired' %}<span class="badge bg-secondary">Expired</span>
283
+ {% elif task.status == 'skipped' %}<span class="badge bg-secondary">Skipped</span>
281
284
  {% endif %}
282
285
  </td>
283
- <td>{% if row.task and row.task.completed_by %}{{ row.task.completed_by.get_full_name|default:row.task.completed_by.username }}{% else %}-{% endif %}</td>
284
- <td>{% if row.task and row.task.completed_at %}{{ row.task.completed_at|date:"Y-m-d H:i" }}{% else %}-{% endif %}</td>
285
- <td>
286
- <a href="{% url 'forms_workflows:sub_workflow_detail' row.instance.id %}" class="btn btn-sm btn-outline-secondary">
287
- <i class="bi bi-eye"></i> View
288
- </a>
289
- </td>
286
+ <td>{% if task.completed_by %}{{ task.completed_by.get_full_name|default:task.completed_by.username }}{% else %}-{% endif %}</td>
287
+ <td>{% if task.completed_at %}{{ task.completed_at|date:"Y-m-d H:i" }}{% else %}-{% endif %}</td>
288
+ <td>{{ task.comments|default:"-" }}</td>
290
289
  </tr>
291
290
  {% endfor %}
291
+ {% endfor %}
292
292
  </tbody>
293
293
  </table>
294
294
  </div>
295
295
  </div>
296
296
  </div>
297
+ {% endfor %}
297
298
  {% endif %}
298
299
 
299
300
  {% else %}
@@ -604,14 +604,13 @@ def submission_detail(request, submission_id):
604
604
  for sg in sub_workflow_groups:
605
605
  sg["section_label"] = sg_name
606
606
 
607
- # Build merged sub-workflow instance rows that combine instance info
608
- # (index, label, status, created) with per-instance approval task info
609
- # (assigned_to, completed_by, completed_at) into a single table.
610
- sub_workflow_instances_merged = None
611
- sub_wf_section_label = None
607
+ # Build per-instance stage groups so each sub-workflow instance is
608
+ # rendered as its own section with stage cards (matching parent style).
609
+ sub_workflow_instance_stages = None
612
610
  sub_wfs = list(
613
611
  submission.sub_workflows.select_related("definition")
614
612
  .prefetch_related(
613
+ "approval_tasks__workflow_stage",
615
614
  "approval_tasks__assigned_to",
616
615
  "approval_tasks__assigned_group",
617
616
  "approval_tasks__completed_by",
@@ -619,34 +618,53 @@ def submission_detail(request, submission_id):
619
618
  .order_by("index")
620
619
  )
621
620
  if sub_wfs:
622
- swf_config = sub_wfs[0].definition if sub_wfs else None
623
- sub_wf_section_label = (
624
- (
625
- swf_config.section_label
626
- if swf_config and swf_config.section_label
627
- else None
628
- )
629
- or (swf_config.sub_workflow.form_definition.name if swf_config else None)
630
- or "Additional Approvals"
631
- )
632
- merged_rows = []
621
+ instance_sections = []
633
622
  for swf in sub_wfs:
634
- tasks = list(swf.approval_tasks.order_by("-completed_at", "id"))
635
- # Pick the most relevant task for display (completed or first pending)
636
- display_task = None
637
- for t in tasks:
638
- if t.status in ("approved", "rejected"):
639
- display_task = t
640
- break
641
- if not display_task and tasks:
642
- display_task = tasks[0]
643
- merged_rows.append(
623
+ tasks = list(
624
+ swf.approval_tasks.select_related("workflow_stage").order_by(
625
+ "stage_number", "id"
626
+ )
627
+ )
628
+ # Group tasks by workflow_stage (like parent stage_groups)
629
+ stage_map: dict = {}
630
+ for task in tasks:
631
+ stage_key = task.workflow_stage_id or f"flat_{task.stage_number}"
632
+ if stage_key not in stage_map:
633
+ stage_name = (
634
+ task.workflow_stage.name
635
+ if task.workflow_stage
636
+ else f"Step {task.stage_number or 1}"
637
+ )
638
+ approval_logic = (
639
+ task.workflow_stage.approval_logic
640
+ if task.workflow_stage
641
+ else "all"
642
+ )
643
+ stage_map[stage_key] = {
644
+ "number": task.stage_number or 0,
645
+ "name": stage_name,
646
+ "approval_logic": approval_logic,
647
+ "tasks": [],
648
+ "approved_count": 0,
649
+ "rejected_count": 0,
650
+ "total_count": 0,
651
+ }
652
+ stage_map[stage_key]["tasks"].append(task)
653
+ stage_map[stage_key]["total_count"] += 1
654
+ if task.status == "approved":
655
+ stage_map[stage_key]["approved_count"] += 1
656
+ elif task.status == "rejected":
657
+ stage_map[stage_key]["rejected_count"] += 1
658
+
659
+ instance_sections.append(
644
660
  {
645
661
  "instance": swf,
646
- "task": display_task,
662
+ "stage_groups": sorted(
663
+ stage_map.values(), key=lambda x: x["number"]
664
+ ),
647
665
  }
648
666
  )
649
- sub_workflow_instances_merged = merged_rows
667
+ sub_workflow_instance_stages = instance_sections
650
668
 
651
669
  # Resolve fresh presigned URLs for any file-upload fields
652
670
  form_data = _resolve_form_data_urls(submission.form_data)
@@ -678,8 +696,7 @@ def submission_detail(request, submission_id):
678
696
  "approval_tasks": approval_tasks,
679
697
  "stage_groups": stage_groups,
680
698
  "sub_workflow_groups": sub_workflow_groups,
681
- "sub_workflow_instances_merged": sub_workflow_instances_merged,
682
- "sub_wf_section_label": sub_wf_section_label,
699
+ "sub_workflow_instance_stages": sub_workflow_instance_stages,
683
700
  "form_data": form_data,
684
701
  "form_data_ordered": form_data_ordered,
685
702
  "approval_field_names": approval_field_names,
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "django-forms-workflows"
3
- version = "0.20.2"
3
+ version = "0.20.4"
4
4
  description = "Enterprise-grade, database-driven form builder with approval workflows and external data integration"
5
5
  license = "LGPL-3.0-only"
6
6
  readme = "README.md"