Files
nexus/modules/pi_control/assets/commands.js
2026-03-07 23:58:40 +01:00

98 lines
3.3 KiB
JavaScript

(() => {
const form = document.querySelector('[data-command-form]');
const list = document.querySelector('[data-command-list]');
if (!form) return;
const idInput = form.querySelector('input[name="id"]');
const labelInput = form.querySelector('input[name="label"]');
const commandInput = form.querySelector('textarea[name="command"]');
const timeoutInput = form.querySelector('input[name="timeout_sec"]');
const adminInput = form.querySelector('input[name="admin_only"]');
const submitBtn = form.querySelector('[data-command-submit]');
const cancelBtn = form.querySelector('[data-command-cancel]');
const resetForm = () => {
if (idInput) idInput.value = '';
if (labelInput) labelInput.value = '';
if (commandInput) commandInput.value = '';
if (timeoutInput) timeoutInput.value = '';
if (adminInput) adminInput.checked = false;
if (submitBtn) submitBtn.textContent = 'Speichern';
};
document.querySelectorAll('[data-command-edit]').forEach((btn) => {
btn.addEventListener('click', () => {
const item = btn.closest('.command-item');
if (!item) return;
if (idInput) idInput.value = item.dataset.commandId || '';
if (labelInput) labelInput.value = item.dataset.label || '';
if (commandInput) commandInput.value = item.dataset.command || '';
if (timeoutInput) timeoutInput.value = item.dataset.timeout || '';
if (adminInput) adminInput.checked = item.dataset.admin === '1';
if (submitBtn) submitBtn.textContent = 'Aktualisieren';
const details = btn.closest('details');
if (details) details.removeAttribute('open');
form.scrollIntoView({ behavior: 'smooth', block: 'start' });
});
});
if (cancelBtn) {
cancelBtn.addEventListener('click', (e) => {
e.preventDefault();
resetForm();
});
}
if (!list) return;
let dragging = null;
list.querySelectorAll('.command-item').forEach((item) => {
item.addEventListener('dragstart', () => {
dragging = item;
item.classList.add('is-dragging');
});
item.addEventListener('dragend', () => {
item.classList.remove('is-dragging');
dragging = null;
saveOrder();
});
});
list.addEventListener('dragover', (e) => {
e.preventDefault();
if (!dragging) return;
const after = getDragAfterElement(list, e.clientY);
if (after == null) {
list.appendChild(dragging);
} else if (after !== dragging) {
list.insertBefore(dragging, after);
}
});
const getDragAfterElement = (container, y) => {
const elements = [...container.querySelectorAll('.command-item:not(.is-dragging)')];
return elements.reduce(
(closest, child) => {
const box = child.getBoundingClientRect();
const offset = y - box.top - box.height / 2;
if (offset < 0 && offset > closest.offset) {
return { offset, element: child };
}
return closest;
},
{ offset: Number.NEGATIVE_INFINITY, element: null }
).element;
};
const saveOrder = () => {
const order = [...list.querySelectorAll('.command-item')].map((el) => el.dataset.commandId);
fetch(window.location.pathname + '?reorder_json=1', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ order }),
cache: 'no-store',
}).catch(() => {});
};
})();