// Admin Dashboard JavaScript - Documentation Style document.addEventListener('DOMContentLoaded', function() { // Highlight active navigation links highlightActiveLinks(); // Setup UI toggles setupUIToggles(); // Setup search functionality setupSearch(); }); // Highlight the current active navigation links function highlightActiveLinks() { const currentPath = window.location.pathname; // Handle top navigation links const navLinks = document.querySelectorAll('.nav-link'); navLinks.forEach(link => { link.classList.remove('active'); const href = link.getAttribute('href'); // Check if current path starts with the nav link path // This allows section links to be highlighted when on sub-pages if (currentPath === href || (href !== '/admin' && currentPath.startsWith(href))) { link.classList.add('active'); } }); // Handle sidebar links const sidebarLinks = document.querySelectorAll('.doc-link'); sidebarLinks.forEach(link => { link.classList.remove('active'); if (link.getAttribute('href') === currentPath) { link.classList.add('active'); // Also highlight parent section if needed const parentSection = link.closest('.sidebar-section'); if (parentSection) { parentSection.classList.add('active-section'); } } }); } // Setup UI toggle functionality function setupUIToggles() { // Toggle sidebar on mobile const menuToggle = document.querySelector('.menu-toggle'); const sidebar = document.querySelector('.sidebar'); if (menuToggle && sidebar) { menuToggle.addEventListener('click', function() { sidebar.classList.toggle('open'); }); } // Toggle log panel const logToggle = document.querySelector('.log-toggle'); const logPanel = document.querySelector('.log-panel'); if (logToggle && logPanel) { logToggle.addEventListener('click', function() { logPanel.classList.toggle('open'); }); } // Setup Docusaurus-style collapsible menu setupTreeviewMenu(); } // Setup sidebar navigation function setupTreeviewMenu() { // Set active sidebar links based on current URL setActiveSidebarLinks(); // Setup collapsible sections setupCollapsibleSections(); } // Set active sidebar links based on current URL function setActiveSidebarLinks() { const currentPath = window.location.pathname; // Find all sidebar links const sidebarLinks = document.querySelectorAll('.sidebar-link'); // Remove any existing active classes sidebarLinks.forEach(link => { link.classList.remove('active'); }); // Find and mark active links let activeFound = false; sidebarLinks.forEach(link => { const linkPath = link.getAttribute('href'); // Check if the current path matches or starts with the link path // For exact matches or if it's a parent path if (currentPath === linkPath || (linkPath !== '/admin' && currentPath.startsWith(linkPath))) { // Mark this link as active link.classList.add('active'); activeFound = true; // Expand the parent section if this link is inside a collapsible section const parentSection = link.closest('.sidebar-content-section')?.parentElement; if (parentSection && parentSection.classList.contains('collapsible')) { parentSection.classList.remove('collapsed'); } } }); } // Setup collapsible sections function setupCollapsibleSections() { // Find all toggle headings const toggleHeadings = document.querySelectorAll('.sidebar-heading.toggle'); // Set all sections as collapsed by default document.querySelectorAll('.sidebar-section.collapsible').forEach(section => { section.classList.add('collapsed'); }); toggleHeadings.forEach(heading => { // Add click event to toggle section heading.addEventListener('click', function() { const section = this.parentElement; section.classList.toggle('collapsed'); }); }); // Open the section that contains the active link const activeLink = document.querySelector('.sidebar-link.active'); if (activeLink) { const parentSection = activeLink.closest('.sidebar-section.collapsible'); if (parentSection) { parentSection.classList.remove('collapsed'); } } } // Refresh processes data without page reload function refreshProcesses() { // Show loading indicator const loadingIndicator = document.getElementById('refresh-loading'); if (loadingIndicator) { loadingIndicator.style.display = 'inline'; } // Get the processes content element const tableContent = document.querySelector('.processes-table-content'); // Use Unpoly to refresh the content if (tableContent && window.up) { // Use Unpoly's API to reload the fragment up.reload('.processes-table-content', { url: '/admin/system/processes-data', headers: { 'X-Requested-With': 'XMLHttpRequest' } }).then(() => { console.log('Process data refreshed successfully via Unpoly'); }).catch(error => { console.error('Error refreshing processes data:', error); }).finally(() => { // Hide loading indicator if (loadingIndicator) { loadingIndicator.style.display = 'none'; } }); } else { // Fallback to fetch if Unpoly is not available fetch('/admin/system/processes-data', { method: 'GET', headers: { 'Accept': 'text/html', 'X-Requested-With': 'XMLHttpRequest' }, cache: 'no-store' }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok: ' + response.status); } return response.text(); }) .then(html => { // Update the processes table content if (tableContent) { // Replace the table content with the new HTML tableContent.innerHTML = html; console.log('Process data refreshed successfully via fetch'); } else { console.error('Could not find processes table content element'); } }) .catch(error => { console.error('Error refreshing processes data:', error); }) .finally(() => { // Hide loading indicator if (loadingIndicator) { loadingIndicator.style.display = 'none'; } }); } } // Note: Logging functionality has been moved to Unpoly-based implementation // Setup search functionality function setupSearch() { const searchInput = document.querySelector('.search-box input'); if (searchInput) { searchInput.addEventListener('keyup', function(e) { if (e.key === 'Enter') { performSearch(this.value); } }); } } // Perform search function performSearch(query) { if (!query.trim()) return; // Log the search query window.adminLog(`Searching for: ${query}`, 'info'); // In a real application, this would send an AJAX request to search the docs // For now, just simulate a search by redirecting to a search results page // window.location.href = `/admin/search?q=${encodeURIComponent(query)}`; // For demo purposes, show a message in the console console.log(`Search query: ${query}`); }