110 lines
4.3 KiB
HTML
110 lines
4.3 KiB
HTML
{% extends "base.html" %}
|
|
{% block content %}
|
|
<div class="back-row top">
|
|
<a class="big-btn small neutral" href="{{ url_for('leitstand_home') }}">← Zurück</a>
|
|
</div>
|
|
<form method="get" action="{{ url_for('leitstand_prioritaet') }}" class="filter-row">
|
|
<span>Maschine:</span>
|
|
<select name="maschine_id" onchange="this.form.submit()">
|
|
{% for m in maschinen %}
|
|
<option value="{{ m.id }}" {% if filter_maschine_id|string == m.id|string %}selected{% endif %}>{{ m.name or ('Maschine ' ~ m.id) }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<button type="submit">Anzeigen</button>
|
|
</form>
|
|
|
|
{% if filter_maschine_id and not auftraege %}
|
|
<div class="empty-state">Keine offenen/pausierten Aufträge für diese Maschine.</div>
|
|
{% elif auftraege %}
|
|
<p class="hint">
|
|
Reihenfolge per Drag & Drop ändern: Auftrag mit der Maus anfassen (Symbol
|
|
☰) und an die gewünschte Position ziehen. Die neue Reihenfolge wird
|
|
automatisch gespeichert. <em>Hinweis: funktioniert am PC/Laptop mit Maus; auf
|
|
reinen Touch-Geräten ohne Maus ist Drag & Drop ggf. eingeschränkt.</em>
|
|
</p>
|
|
<noscript><div class="error-box">Für die Sortierung per Drag & Drop wird JavaScript benötigt.</div></noscript>
|
|
<div class="priority-list" id="priority-list" data-maschine-id="{{ filter_maschine_id }}">
|
|
{% for a in auftraege %}
|
|
<div class="priority-item" draggable="true" data-id="{{ a.id }}">
|
|
<span class="drag-handle">☰</span>
|
|
<span class="sid-badge">#{{ loop.index }}</span>
|
|
<span class="priority-item-info">
|
|
<span>{{ a.auftragsnummer }}</span>
|
|
{% if a.artikel %}<span class="priority-item-artikel">{{ a.artikel }}</span>{% endif %}
|
|
</span>
|
|
<span class="tag">{{ a.status_label }}</span>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
<div class="save-indicator" id="save-indicator" aria-live="polite"></div>
|
|
<script>
|
|
(function () {
|
|
var list = document.getElementById('priority-list');
|
|
if (!list) return;
|
|
var indicator = document.getElementById('save-indicator');
|
|
|
|
function getDragAfterElement(container, y) {
|
|
var items = Array.prototype.slice.call(container.querySelectorAll('.priority-item:not(.dragging)'));
|
|
return items.reduce(function (closest, child) {
|
|
var box = child.getBoundingClientRect();
|
|
var offset = y - box.top - box.height / 2;
|
|
if (offset < 0 && offset > closest.offset) {
|
|
return { offset: offset, element: child };
|
|
}
|
|
return closest;
|
|
}, { offset: -Infinity, element: null }).element;
|
|
}
|
|
|
|
function updateBadges() {
|
|
Array.prototype.forEach.call(list.querySelectorAll('.priority-item'), function (el, idx) {
|
|
var badge = el.querySelector('.sid-badge');
|
|
if (badge) badge.textContent = '#' + (idx + 1);
|
|
});
|
|
}
|
|
|
|
function persistOrder() {
|
|
var ids = Array.prototype.map.call(list.querySelectorAll('.priority-item'), function (el) {
|
|
return el.getAttribute('data-id');
|
|
});
|
|
updateBadges();
|
|
if (indicator) indicator.textContent = 'Speichere…';
|
|
fetch("{{ url_for('leitstand_prioritaet_reihenfolge') }}", {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ maschine_id: list.getAttribute('data-maschine-id'), ids: ids })
|
|
}).then(function (resp) {
|
|
if (indicator) indicator.textContent = resp.ok ? 'Gespeichert.' : 'Fehler beim Speichern.';
|
|
}).catch(function () {
|
|
if (indicator) indicator.textContent = 'Fehler beim Speichern.';
|
|
});
|
|
}
|
|
|
|
list.addEventListener('dragstart', function (e) {
|
|
var item = e.target.closest('.priority-item');
|
|
if (!item) return;
|
|
item.classList.add('dragging');
|
|
e.dataTransfer.effectAllowed = 'move';
|
|
});
|
|
|
|
list.addEventListener('dragend', function (e) {
|
|
var item = e.target.closest('.priority-item');
|
|
if (item) item.classList.remove('dragging');
|
|
persistOrder();
|
|
});
|
|
|
|
list.addEventListener('dragover', function (e) {
|
|
e.preventDefault();
|
|
var dragging = list.querySelector('.dragging');
|
|
if (!dragging) return;
|
|
var after = getDragAfterElement(list, e.clientY);
|
|
if (after == null) {
|
|
list.appendChild(dragging);
|
|
} else {
|
|
list.insertBefore(dragging, after);
|
|
}
|
|
});
|
|
})();
|
|
</script>
|
|
{% endif %}
|
|
{% endblock %}
|