diff --git a/public/js/app.js b/public/js/app.js index 990f628..f44fe96 100755 --- a/public/js/app.js +++ b/public/js/app.js @@ -4,21 +4,28 @@ document.addEventListener('DOMContentLoaded', function() { // Global function for editing item from tree window.editItem = function(id) { - // Create a mock button to reuse handleEditItem const mockBtn = { getAttribute: (attr) => attr === 'data-id' ? id : null }; handleEditItem.call(mockBtn); }; - // Function to toggle category children - window.toggleCategory = function(span) { - const li = span.parentElement; - const ul = li.querySelector('ul'); // First ul is children - if (ul) { - ul.style.display = ul.style.display === 'none' ? 'block' : 'none'; + // Function to toggle tree nodes + window.toggleNode = function(element) { + const li = element.closest('li'); + const childUl = li.querySelector(':scope > ul'); + if (childUl) { + const isHidden = childUl.style.display === 'none'; + childUl.style.display = isHidden ? 'block' : 'none'; + const icon = element.querySelector('i'); + if (icon) { + if (isHidden) { + icon.className = 'bi bi-folder-fill text-warning'; + } else { + icon.className = 'bi bi-folder text-warning'; + } + } } }; - // --- Helper Functions --- function setPageTitle(title) { document.title = `${appName} - ${title}`; } @@ -27,11 +34,24 @@ document.addEventListener('DOMContentLoaded', function() { mainContent.innerHTML = '
Geen afbeelding
'; } - // Populate category select const categorySelect = document.getElementById('edit_item_category_id'); categorySelect.innerHTML = ''; fetch('/api/categories/list') @@ -313,6 +300,10 @@ document.addEventListener('DOMContentLoaded', function() { }); categorySelect.value = data.category_id || ''; const modal = new bootstrap.Modal(document.getElementById('editItemModal')); + const saveEditItemBtn = document.getElementById('saveEditItemBtn'); + if (saveEditItemBtn) { + saveEditItemBtn.addEventListener('click', handleSaveEditItem); + } modal.show(); }); } else { @@ -335,6 +326,7 @@ document.addEventListener('DOMContentLoaded', function() { .then(data => { if (data.success) { this.closest('li').remove(); + reloadTree(); // Reload tree after deletion } else { alert(data.error || 'Error deleting part'); } @@ -356,6 +348,7 @@ document.addEventListener('DOMContentLoaded', function() { .then(data => { if (data.success) { fetchContent('/categories', false); + reloadTree(); // Reload tree after adding } else { alert(data.error || 'Error adding category'); } @@ -395,15 +388,25 @@ document.addEventListener('DOMContentLoaded', function() { .then(response => response.json()) .then(data => { if (data.success) { - bootstrap.Modal.getInstance(document.getElementById('editItemModal')).hide(); - fetchContent('/', false); // Reload overview + // Hide modal + const modalElement = document.getElementById('editItemModal'); + if (modalElement) { + modalElement.classList.remove('show', 'showing'); + modalElement.style.display = 'none'; + modalElement.setAttribute('aria-hidden', 'true'); + document.body.classList.remove('modal-open'); + const backdrops = document.querySelectorAll(' .modal-backdrop'); + backdrops.forEach(backdrop => backdrop.remove()); + } + fetchContent('/', false); + reloadTree(); // Reload tree after updating } else { alert(data.error || 'Error updating part'); } }) .catch(error => { - console.error('Error:', error); - alert('Error updating part'); + console.error('Update error:', error); + alert('Error updating part: ' + error.message); }); } @@ -432,21 +435,30 @@ document.addEventListener('DOMContentLoaded', function() { .then(response => response.json()) .then(data => { if (data.success) { - bootstrap.Modal.getInstance(document.getElementById('editCategoryModal')).hide(); + // Hide modal + const modalElement = document.getElementById('editCategoryModal'); + if (modalElement) { + modalElement.classList.remove('show', 'showing'); + modalElement.style.display = 'none'; + modalElement.setAttribute('aria-hidden', 'true'); + document.body.classList.remove('modal-open'); + const backdrops = document.querySelectorAll(' .modal-backdrop'); + backdrops.forEach(backdrop => backdrop.remove()); + } fetchContent('/categories', false); + reloadTree(); // Reload tree after updating } else { alert(data.error || 'Error updating category'); } }) .catch(error => { - console.error('Error:', error); - alert('Error updating category'); + console.error('Update error:', error); + alert('Error updating category: ' + error.message); }); } function handleEditCategory() { const id = this.getAttribute('data-id'); - // Fetch current category data fetch('/api/categories/' + id) .then(response => { if (!response.ok) { @@ -458,7 +470,6 @@ document.addEventListener('DOMContentLoaded', function() { if (data && !data.error) { document.getElementById('edit_category_id').value = data.id; document.getElementById('edit_category_name').value = data.name; - // Populate parent select, excluding current category const parentSelect = document.getElementById('edit_parent_category_id'); parentSelect.innerHTML = ''; fetch('/api/categories/list') @@ -474,6 +485,10 @@ document.addEventListener('DOMContentLoaded', function() { }); parentSelect.value = data.parent_id || ''; const modal = new bootstrap.Modal(document.getElementById('editCategoryModal')); + const saveEditCategoryBtn = document.getElementById('saveEditCategoryBtn'); + if (saveEditCategoryBtn) { + saveEditCategoryBtn.addEventListener('click', handleSaveEditCategory); + } modal.show(); }); } else { @@ -496,6 +511,7 @@ document.addEventListener('DOMContentLoaded', function() { .then(data => { if (data.success) { this.closest('li').remove(); + reloadTree(); // Reload tree after deletion } else { alert(data.error || 'Error deleting category'); }