153 lines
4.9 KiB
JavaScript

// ECM Control Frontend JavaScript
document.addEventListener('DOMContentLoaded', function() {
// Auto-hide Bootstrap modals after successful HTMX requests
document.body.addEventListener('htmx:afterRequest', function(event) {
if (event.detail.successful) {
// Find any open modals and hide them
const openModals = document.querySelectorAll('.modal.show');
openModals.forEach(modal => {
const modalInstance = bootstrap.Modal.getInstance(modal);
if (modalInstance) {
modalInstance.hide();
}
});
// Show success notification
showNotification('Operation completed successfully', 'success');
} else {
// Show error notification
showNotification('Operation failed. Please try again.', 'error');
}
});
// Clear form fields when modal is hidden
document.querySelectorAll('.modal').forEach(modal => {
modal.addEventListener('hidden.bs.modal', function() {
const form = this.querySelector('form');
if (form) {
form.reset();
}
});
});
});
// Show notification function
function showNotification(message, type = 'info') {
const alertClass = type === 'success' ? 'alert-success' :
type === 'error' ? 'alert-danger' : 'alert-info';
const notification = document.createElement('div');
notification.className = `alert ${alertClass} alert-dismissible fade show position-fixed`;
notification.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;';
notification.innerHTML = `
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
document.body.appendChild(notification);
// Auto-remove after 5 seconds
setTimeout(() => {
if (notification.parentNode) {
notification.remove();
}
}, 5000);
}
// Confirm deletion dialogs
document.body.addEventListener('click', function(event) {
const deleteBtn = event.target.closest('[hx-delete]');
if (deleteBtn && deleteBtn.hasAttribute('hx-confirm')) {
const confirmMessage = deleteBtn.getAttribute('hx-confirm');
if (!confirm(confirmMessage)) {
event.preventDefault();
event.stopPropagation();
}
}
});
// Auto-refresh dashboard every 30 seconds
if (window.location.pathname === '/') {
setInterval(() => {
// Only refresh if page is visible
if (!document.hidden) {
window.location.reload();
}
}, 30000);
}
// Form validation helpers
function validateRecipeForm(form) {
const name = form.querySelector('[name="name"]').value.trim();
const gramsOut = parseFloat(form.querySelector('[name="grams_out"]').value);
const timeoutSeconds = parseInt(form.querySelector('[name="timeout_seconds"]').value);
if (!name) {
showNotification('Recipe name is required', 'error');
return false;
}
if (gramsOut <= 0 || gramsOut > 100) {
showNotification('Grams out must be between 0 and 100', 'error');
return false;
}
if (timeoutSeconds <= 0 || timeoutSeconds > 300) {
showNotification('Timeout must be between 1 and 300 seconds', 'error');
return false;
}
return true;
}
function validateButtonForm(form) {
const name = form.querySelector('[name="name"]').value.trim();
const gpioPin = parseInt(form.querySelector('[name="gpio_pin"]').value);
if (!name) {
showNotification('Button name is required', 'error');
return false;
}
if (gpioPin < 0 || gpioPin > 40) {
showNotification('GPIO pin must be between 0 and 40', 'error');
return false;
}
return true;
}
// Add form validation to modals
document.addEventListener('submit', function(event) {
const form = event.target;
if (form.matches('#addRecipeModal form')) {
if (!validateRecipeForm(form)) {
event.preventDefault();
}
}
if (form.matches('#addButtonModal form')) {
if (!validateButtonForm(form)) {
event.preventDefault();
}
}
});
// Keyboard shortcuts
document.addEventListener('keydown', function(event) {
// Ctrl/Cmd + N to add new recipe on recipes page
if ((event.ctrlKey || event.metaKey) && event.key === 'n' && window.location.pathname === '/recipes') {
event.preventDefault();
const modal = new bootstrap.Modal(document.getElementById('addRecipeModal'));
modal.show();
}
// Ctrl/Cmd + B to add new button on buttons page
if ((event.ctrlKey || event.metaKey) && event.key === 'b' && window.location.pathname === '/buttons') {
event.preventDefault();
const modal = new bootstrap.Modal(document.getElementById('addButtonModal'));
modal.show();
}
});