mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-22 23:31:08 -05:00
Add test utilities and state machine diagrams for FSM models
- Introduced reusable test utilities in `backend/tests/utils` for FSM transitions, HTMX interactions, and common scenarios. - Added factory functions for creating test submissions, parks, rides, and photo submissions. - Implemented assertion helpers for verifying state changes, toast notifications, and transition logs. - Created comprehensive state machine diagrams for all FSM-enabled models in `docs/STATE_DIAGRAMS.md`, detailing states, transitions, and guard conditions.
This commit is contained in:
58
backend/templates/htmx/state_actions.html
Normal file
58
backend/templates/htmx/state_actions.html
Normal file
@@ -0,0 +1,58 @@
|
||||
{% comment %}
|
||||
FSM State Actions Partial Template
|
||||
|
||||
Renders available transition buttons for an FSM-enabled object.
|
||||
Uses HTMX for seamless state transitions with toast notifications.
|
||||
|
||||
Required context:
|
||||
- object: The FSM-enabled model instance
|
||||
- user: The current user (usually request.user)
|
||||
|
||||
Optional context:
|
||||
- target_id: The ID of the element to swap after transition (defaults to object-{{ object.id }})
|
||||
- button_size: 'sm', 'md', or 'lg' (defaults to 'md')
|
||||
- show_labels: Whether to show button labels (defaults to true)
|
||||
- inline: Whether to render buttons inline (defaults to false)
|
||||
{% endcomment %}
|
||||
{% load fsm_tags %}
|
||||
|
||||
{% get_available_transitions object user as transitions %}
|
||||
|
||||
{% if transitions %}
|
||||
<div class="fsm-actions flex {% if inline %}flex-row gap-2{% else %}flex-wrap gap-2{% endif %}"
|
||||
id="actions-{{ object.id }}">
|
||||
{% for transition in transitions %}
|
||||
<button
|
||||
type="button"
|
||||
hx-post="{% url 'core:fsm_transition' app_label=object|app_label model_name=object|model_name pk=object.pk transition_name=transition.name %}"
|
||||
hx-target="#{{ target_id|default:object|default_target_id }}"
|
||||
hx-swap="outerHTML"
|
||||
{% if transition.requires_confirm %}
|
||||
hx-confirm="{{ transition.confirm_message|default:'Are you sure?' }}"
|
||||
{% endif %}
|
||||
hx-indicator="#loading-{{ object.id }}"
|
||||
class="inline-flex items-center justify-center gap-1.5 px-{% if button_size == 'sm' %}2.5 py-1.5 text-xs{% elif button_size == 'lg' %}5 py-3 text-base{% else %}4 py-2.5 text-sm{% endif %} font-medium rounded-lg transition-all duration-200 shadow-xs hover:shadow-md
|
||||
{% if transition.style == 'green' %}
|
||||
bg-green-600 text-white hover:bg-green-500 dark:bg-green-700 dark:hover:bg-green-600
|
||||
{% elif transition.style == 'red' %}
|
||||
bg-red-600 text-white hover:bg-red-500 dark:bg-red-700 dark:hover:bg-red-600
|
||||
{% elif transition.style == 'yellow' %}
|
||||
bg-yellow-600 text-white hover:bg-yellow-500 dark:bg-yellow-700 dark:hover:bg-yellow-600
|
||||
{% elif transition.style == 'blue' %}
|
||||
bg-blue-600 text-white hover:bg-blue-500 dark:bg-blue-700 dark:hover:bg-blue-600
|
||||
{% else %}
|
||||
bg-gray-600 text-white hover:bg-gray-500 dark:bg-gray-700 dark:hover:bg-gray-600
|
||||
{% endif %}">
|
||||
<i class="fas fa-{{ transition.icon|default:'arrow-right' }}"></i>
|
||||
{% if show_labels|default:True %}
|
||||
<span>{{ transition.label }}</span>
|
||||
{% endif %}
|
||||
</button>
|
||||
{% endfor %}
|
||||
|
||||
<!-- Loading indicator -->
|
||||
<span id="loading-{{ object.id }}" class="htmx-indicator inline-flex items-center">
|
||||
<i class="fas fa-spinner fa-spin text-blue-500"></i>
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user