sortable list now updates order of definitions
This commit is contained in:
parent
26398e3ac1
commit
aedd8801ce
|
@ -17,7 +17,6 @@
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h4>{% trans "State Definitions" %}</h4>
|
<h4>{% trans "State Definitions" %}</h4>
|
||||||
{% if state_definitions %}
|
{% if state_definitions %}
|
||||||
<p>{% trans "Move state definitions to reorder" %}</p>
|
|
||||||
<table class="table table-hover table-mb-4">
|
<table class="table table-hover table-mb-4">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -28,11 +27,11 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="sortable_list">
|
<tbody id="sortable_list">
|
||||||
{% for state_definition in state_definitions %}
|
{% for state_definition in state_definitions %}
|
||||||
<tr data-id="{{ state_definition.id }}">
|
<tr data-lookup="{{ state_definition.id }}" style="cursor: pointer;">
|
||||||
<td class="order-number">{{ state_definition.order }}</td>
|
<td class="order-number">{{ state_definition.order }}</td>
|
||||||
<td>{{ state_definition.state }}</td>
|
<td>{{ state_definition.state }}</td>
|
||||||
<td class="text-end">
|
<td class="text-end">
|
||||||
<button type="button" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#deleteStateModal{{ state_definition.id }}">
|
<button type="button" id="delete-btn" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#deleteStateModal{{ state_definition.id }}">
|
||||||
{% trans "Delete" %}
|
{% trans "Delete" %}
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
|
@ -40,10 +39,12 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<form id="orderingForm" method="post">
|
|
||||||
|
<p class="text-end transparent">{% trans "Move state definitions to reorder" %}</p>
|
||||||
|
<form id="orderingForm" method="post" action="{% url 'admin:update_state_order' %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input type="hidden" id="orderingInput" name="ordering">
|
<input type="hidden" id="orderingInput" name="ordering">
|
||||||
<button id="saveOrderBtn" class="btn btn-outline-primary mt-5 float-start" style="display: none;">{% trans "Save" %}</button>
|
<button id="saveOrderBtn" disabled="true" class="btn btn-success mt-5 float-start" >{% trans "Update Order" %}</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,7 +94,8 @@
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>{% trans "Are you sure you want to delete this state definition?" %}</p>
|
<strong class="mb-2">{% trans "Are you sure you want to delete this state definition?" %}</strong>
|
||||||
|
<p>{% trans "Any change in order will not be saved" %}</p>
|
||||||
<div class="d-flex align-items-center mt-3">
|
<div class="d-flex align-items-center mt-3">
|
||||||
<span class="me-4 display-7">{{ state_definition.order }}</span>
|
<span class="me-4 display-7">{{ state_definition.order }}</span>
|
||||||
<div>
|
<div>
|
||||||
|
@ -116,19 +118,21 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
//following https://dev.to/nemecek_f/django-how-to-let-user-re-order-sort-table-of-content-with-drag-and-drop-3nlp
|
//following https://dev.to/nemecek_f/django-how-to-let-user-re-order-sort-table-of-content-with-drag-and-drop-3nlp
|
||||||
const saveOrderingButton = document.getElementById('saveOrdering');
|
const saveOrderingButton = document.getElementById('saveOrderBtn');
|
||||||
const orderingForm = document.getElementById('orderingForm');
|
const orderingForm = document.getElementById('orderingForm');
|
||||||
const formInput = orderingForm.querySelector('#orderingInput');
|
const formInput = orderingForm.querySelector('#orderingInput');
|
||||||
|
const sortable_table = document.getElementById('sortable_list');
|
||||||
|
|
||||||
const sortable = new Sortable(document.getElementById('sortable_list'), {
|
const sortable = new Sortable(sortable_table, {
|
||||||
animation: 150,
|
animation: 150,
|
||||||
onEnd: function (/**Event*/evt) {
|
swapThreshold: 0.10,
|
||||||
document.getElementById('saveOrderBtn').style.display = 'block';
|
onChange: () => {
|
||||||
|
saveOrderingButton.disabled = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function saveOrdering() {
|
function saveOrdering() {
|
||||||
const rows = document.getElementById("groups").querySelectorAll('tr');
|
const rows = sortable_table.querySelectorAll('tr');
|
||||||
let ids = [];
|
let ids = [];
|
||||||
for (let row of rows) {
|
for (let row of rows) {
|
||||||
ids.push(row.dataset.lookup);
|
ids.push(row.dataset.lookup);
|
||||||
|
@ -137,6 +141,8 @@
|
||||||
orderingForm.submit();
|
orderingForm.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveOrderingButton.addEventListener('click', saveOrdering);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,4 +13,5 @@ urlpatterns = [
|
||||||
path("states/", views.StatesPanelView.as_view(), name="states"),
|
path("states/", views.StatesPanelView.as_view(), name="states"),
|
||||||
path("states/add", views.AddStateDefinitionView.as_view(), name="add_state_definition"),
|
path("states/add", views.AddStateDefinitionView.as_view(), name="add_state_definition"),
|
||||||
path('states/delete/<int:pk>', views.DeleteStateDefinitionView.as_view(), name='delete_state_definition'),
|
path('states/delete/<int:pk>', views.DeleteStateDefinitionView.as_view(), name='delete_state_definition'),
|
||||||
|
path('states/update_order/', views.UpdateStateOrderView.as_view(), name='update_state_order'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from smtplib import SMTPException
|
from smtplib import SMTPException
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404, redirect, Http404
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.contrib.messages.views import SuccessMessageMixin
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
from django.views.generic.base import TemplateView, ContextMixin
|
from django.views.generic.base import TemplateView, ContextMixin
|
||||||
|
@ -11,8 +11,9 @@ from django.views.generic.edit import (
|
||||||
DeleteView,
|
DeleteView,
|
||||||
)
|
)
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError, transaction
|
||||||
from dashboard.mixins import DashboardView, Http403
|
from dashboard.mixins import DashboardView, Http403
|
||||||
|
from admin.forms import OrderingStateForm
|
||||||
from user.models import User, Institution
|
from user.models import User, Institution
|
||||||
from admin.email import NotifyActivateUserByEmail
|
from admin.email import NotifyActivateUserByEmail
|
||||||
from action.models import StateDefinition
|
from action.models import StateDefinition
|
||||||
|
@ -181,3 +182,26 @@ class DeleteStateDefinitionView(AdminView, StateDefinitionContextMixin, SuccessM
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
return super().delete(request, *args, **kwargs)
|
return super().delete(request, *args, **kwargs)
|
||||||
|
|
||||||
|
class UpdateStateOrderView(AdminView, TemplateView):
|
||||||
|
success_url = reverse_lazy('admin:states')
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
form = OrderingStateForm(request.POST)
|
||||||
|
|
||||||
|
if form.is_valid():
|
||||||
|
ordered_ids = form.cleaned_data["ordering"].split(',')
|
||||||
|
|
||||||
|
with transaction.atomic():
|
||||||
|
current_order = 1
|
||||||
|
for lookup_id in ordered_ids:
|
||||||
|
state_definition = StateDefinition.objects.get(id=lookup_id)
|
||||||
|
state_definition.order = current_order
|
||||||
|
state_definition.save()
|
||||||
|
current_order += 1
|
||||||
|
|
||||||
|
messages.success(self.request, _("Order changed succesfuly."))
|
||||||
|
return redirect(self.success_url)
|
||||||
|
else:
|
||||||
|
return Http404
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue