Fix domains tab navigation to prevent page breakage

- Prevent re-initialization when clicking domains button while already on domains tab
- Add navigateToTab helper function to intelligently handle tab navigation
- Redirect #domains hash to index (no hash) since domains is the default tab
- Update all navigation buttons to use navigateToTab helper
- Handle both initial load and hashchange events to remove #domains hash

This fixes the issue where navigating to or clicking the domains tab when
already viewing it would break the page by clearing and re-rendering content.
This commit is contained in:
Raven Scott
2025-12-26 22:16:14 -05:00
parent 3466d17eda
commit 1630370ff4
2 changed files with 68 additions and 13 deletions
+56 -1
View File
@@ -1,12 +1,23 @@
// Main admin entry point - loads all modules and initializes the application
// Load order: config -> state -> utils -> core -> notifications -> ws-client -> ui modules -> main init
// Redirect if hash is 'domains' on initial load (should use no hash for default)
if (location.hash === '#domains') {
// Replace state to remove hash without triggering hashchange
history.replaceState(null, '', location.pathname + location.search);
}
// Initialize when DOM is ready
function initializeApp() {
// showTab function - must be defined after all modules are loaded
function showTab(tabId) {
document.querySelectorAll('.tab-content').forEach(el => el.classList.add('hidden'));
// If we're already on this tab and it's visible, don't do anything to avoid breaking the page
const tabEl = document.getElementById(tabId);
if (window.activeTab === tabId && tabEl && !tabEl.classList.contains('hidden')) {
return;
}
document.querySelectorAll('.tab-content').forEach(el => el.classList.add('hidden'));
if (tabEl) tabEl.classList.remove('hidden');
window.activeTab = tabId;
@@ -238,9 +249,53 @@ if (document.readyState === 'loading') {
initializeApp();
}
// Navigation helper function - only sets hash if not already on that tab
function navigateToTab(tabId) {
// Get current tab - check hash first, then fallback to activeTab
const currentHash = location.hash.substring(1);
let currentTab;
if (currentHash && document.getElementById(currentHash)) {
currentTab = currentHash;
} else {
// No hash or invalid hash - use activeTab or default to 'domains'
currentTab = window.activeTab || 'domains';
}
// If we're already on this tab, don't change the hash
// This prevents breaking the page when clicking the same tab button
if (currentTab === tabId) {
return;
}
// For domains tab, navigate to index with no hash (since domains is the default)
if (tabId === 'domains') {
history.replaceState(null, '', location.pathname + location.search);
if (window.showTab) {
window.showTab('domains');
}
return;
}
// Only set hash if we're not already on this tab
location.hash = tabId;
}
window.navigateToTab = navigateToTab;
// Handle hash changes
window.addEventListener('hashchange', () => {
const tabId = location.hash.substring(1);
// Redirect if hash is 'domains' (should use no hash for default)
if (tabId === 'domains') {
history.replaceState(null, '', location.pathname + location.search);
// Show domains tab without hash
if (window.showTab) {
window.showTab('domains');
}
return;
}
if (tabId && document.getElementById(tabId) && window.showTab) {
window.showTab(tabId);
}
+12 -12
View File
@@ -42,23 +42,23 @@
<nav class="flex justify-center mb-8 space-x-4 flex-wrap">
<!-- Core Management -->
<button onclick="location.hash = 'domains';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Domains</button>
<button onclick="location.hash = 'host';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Host</button>
<button onclick="location.hash = 'entries';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Entries</button>
<button onclick="location.hash = 'peers';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Peers</button>
<button onclick="if(window.navigateToTab) window.navigateToTab('domains'); else location.hash = 'domains';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Domains</button>
<button onclick="if(window.navigateToTab) window.navigateToTab('host'); else location.hash = 'host';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Host</button>
<button onclick="if(window.navigateToTab) window.navigateToTab('entries'); else location.hash = 'entries';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Entries</button>
<button onclick="if(window.navigateToTab) window.navigateToTab('peers'); else location.hash = 'peers';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Peers</button>
<!-- Network -->
<button onclick="location.hash = 'local-dns';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Local DNS</button>
<button onclick="location.hash = 'interfaces';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Interfaces</button>
<button onclick="if(window.navigateToTab) window.navigateToTab('local-dns'); else location.hash = 'local-dns';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Local DNS</button>
<button onclick="if(window.navigateToTab) window.navigateToTab('interfaces'); else location.hash = 'interfaces';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Interfaces</button>
<!-- Security -->
<button onclick="location.hash = 'certs';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Certificates</button>
<button onclick="if(window.navigateToTab) window.navigateToTab('certs'); else location.hash = 'certs';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Certificates</button>
<!-- Monitoring -->
<button onclick="location.hash = 'stats';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Stats</button>
<button onclick="location.hash = 'logs';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Logs</button>
<button onclick="if(window.navigateToTab) window.navigateToTab('stats'); else location.hash = 'stats';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Stats</button>
<button onclick="if(window.navigateToTab) window.navigateToTab('logs'); else location.hash = 'logs';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Logs</button>
<!-- Configuration -->
<button onclick="location.hash = 'backups';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Backups</button>
<button onclick="if(window.navigateToTab) window.navigateToTab('backups'); else location.hash = 'backups';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Backups</button>
<!-- Plugins -->
<button onclick="location.hash = 'plugins';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Plugins</button>
<button onclick="location.hash = 'settings';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Settings</button>
<button onclick="if(window.navigateToTab) window.navigateToTab('plugins'); else location.hash = 'plugins';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Plugins</button>
<button onclick="if(window.navigateToTab) window.navigateToTab('settings'); else location.hash = 'settings';" class="px-4 py-2 bg-primary text-white rounded hover:bg-primary-hover m-1">Settings</button>
</nav>
<div id="domains" class="tab-content hidden flex flex-col" style="height: calc(100vh - 200px); max-height: calc(100vh - 200px);">