lot_tag list can be reordered
This commit is contained in:
parent
8abc0a4a30
commit
913fb663fd
|
@ -16,8 +16,13 @@
|
|||
<div class="col">
|
||||
{% if lot_tags_edit %}
|
||||
<table class="table table-hover table-bordered align-middle">
|
||||
<caption class="text-muted small">
|
||||
{% trans 'Inbox order CANNOT be changed' %}
|
||||
</caption>
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th scope="col" class="text-center" width="5%"> #
|
||||
</th>
|
||||
<th scope="col">{% trans "Lot Group Name" %}
|
||||
</th>
|
||||
<th scope="col" width="15%" class="text-center">{% trans "Actions" %}
|
||||
|
@ -26,7 +31,15 @@
|
|||
</thead>
|
||||
<tbody id="sortable_list">
|
||||
{% for tag in lot_tags_edit %}
|
||||
<tr {% if tag.id == 1 %} class="bg-light" {% endif %}>
|
||||
<tr {% if tag.id == 1 %} class="bg-light no-sort"{% endif %}
|
||||
data-lookup="{{ tag.id }}"
|
||||
style="cursor: grab;" >
|
||||
|
||||
<td class="">
|
||||
<i class="bi bi-grip-vertical" aria-hidden="true" >
|
||||
<strong class="ps-2">{{ tag.order }}</strong>
|
||||
</i>
|
||||
</td>
|
||||
<td class="font-monospace">
|
||||
{{ tag.name }}
|
||||
</td>
|
||||
|
@ -56,6 +69,11 @@
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
<form id="orderingForm" method="post" action="{% url 'admin:update_lot_tag_order' %}">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" id="orderingInput" name="ordering">
|
||||
<button id="saveOrderBtn" class="btn btn-success mt-5 float-start collapse" >{% trans "Update Order" %}</button>
|
||||
</form>
|
||||
|
||||
{% else %}
|
||||
<div class="alert alert-primary text-center mt-5" role="alert">
|
||||
|
@ -186,4 +204,42 @@
|
|||
</div>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
<script>
|
||||
//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('saveOrderBtn');
|
||||
const orderingForm = document.getElementById('orderingForm');
|
||||
const formInput = orderingForm.querySelector('#orderingInput');
|
||||
const sortable_table = document.getElementById('sortable_list');
|
||||
const inbox_row = document.getElementById('inbox');
|
||||
|
||||
const sortable = new Sortable(sortable_table, {
|
||||
animation: 150,
|
||||
swapThreshold: 0.10,
|
||||
filter: '.no-sort',
|
||||
onChange: () => {
|
||||
//TODO: change hide/show animation to a nicer one
|
||||
const collapse = new bootstrap.Collapse(saveOrderingButton, {
|
||||
toggle: false
|
||||
});
|
||||
collapse.show();
|
||||
}
|
||||
});
|
||||
|
||||
function saveOrdering() {
|
||||
const rows = sortable_table.querySelectorAll('tr');
|
||||
let ids = [];
|
||||
for (let row of rows) {
|
||||
ids.push(row.dataset.lookup);
|
||||
}
|
||||
formInput.value = ids.join(',');
|
||||
orderingForm.submit();
|
||||
}
|
||||
|
||||
saveOrderingButton.addEventListener('click', saveOrdering);
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -19,4 +19,5 @@ urlpatterns = [
|
|||
path("lot/add", views.AddLotTagView.as_view(), name="add_lot_tag"),
|
||||
path("lot/delete/<int:pk>", views.DeleteLotTagView.as_view(), name='delete_lot_tag'),
|
||||
path("lot/edit/<int:pk>/", views.UpdateLotTagView.as_view(), name='edit_lot_tag'),
|
||||
path("lot/update_order/", views.UpdateLotTagOrderView.as_view(), name='update_lot_tag_order'),
|
||||
]
|
||||
|
|
|
@ -206,6 +206,30 @@ class UpdateLotTagView(AdminView, UpdateView):
|
|||
return response
|
||||
|
||||
|
||||
class UpdateLotTagOrderView(AdminView, TemplateView):
|
||||
success_url = reverse_lazy('admin:tag_panel')
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = OrderingStateForm(request.POST)
|
||||
|
||||
if form.is_valid():
|
||||
ordered_ids = form.cleaned_data["ordering"].split(',')
|
||||
|
||||
with transaction.atomic():
|
||||
#TODO: log on institution wide logging - if implemented -
|
||||
current_order = 2
|
||||
for lookup_id in ordered_ids:
|
||||
lot_tag = LotTag.objects.get(id=lookup_id)
|
||||
lot_tag.order = current_order
|
||||
lot_tag.save()
|
||||
current_order += 1
|
||||
|
||||
messages.success(self.request, _("Order changed succesfuly."))
|
||||
return redirect(self.success_url)
|
||||
else:
|
||||
return Http404
|
||||
|
||||
|
||||
class InstitutionView(AdminView, UpdateView):
|
||||
template_name = "institution.html"
|
||||
title = _("Edit institution")
|
||||
|
|
|
@ -35,7 +35,7 @@ class DashboardView(LoginRequiredMixin):
|
|||
context = super().get_context_data(**kwargs)
|
||||
lot_tags = LotTag.objects.filter(
|
||||
owner=self.request.user.institution,
|
||||
)
|
||||
).order_by('order')
|
||||
context.update({
|
||||
"commit_id": settings.COMMIT,
|
||||
'title': self.title,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.db import models
|
||||
from django.db.models import Max
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from utils.constants import (
|
||||
STR_SM_SIZE,
|
||||
|
@ -16,11 +17,28 @@ class LotTag(models.Model):
|
|||
owner = models.ForeignKey(Institution, on_delete=models.CASCADE)
|
||||
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
|
||||
inbox = models.BooleanField(default=False)
|
||||
order = models.PositiveIntegerField(default=0)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.pk:
|
||||
# set the order to be last
|
||||
max_order = LotTag.objects.filter(owner=self.owner).aggregate(Max('order'))['order__max']
|
||||
self.order = (max_order or 0) + 1
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
institution = self.owner
|
||||
order = self.order
|
||||
super().delete(*args, **kwargs)
|
||||
# Adjust the order of other instances
|
||||
LotTag.objects.filter(owner=institution, order__gt=order).update(order=models.F('order') - 1)
|
||||
|
||||
|
||||
class DeviceLot(models.Model):
|
||||
lot = models.ForeignKey("Lot", on_delete=models.CASCADE)
|
||||
device_id = models.CharField(max_length=STR_EXTEND_SIZE, blank=False, null=False)
|
||||
|
@ -51,6 +69,7 @@ class Lot(models.Model):
|
|||
def remove(self, v):
|
||||
for d in DeviceLot.objects.filter(lot=self, device_id=v):
|
||||
d.delete()
|
||||
|
||||
@property
|
||||
def devices(self):
|
||||
return DeviceLot.objects.filter(lot=self)
|
||||
|
|
Loading…
Reference in a new issue