From 79d99cfd7ab98ff07798c05659a166fb70f20439 Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Sun, 28 Jun 2026 15:02:57 +0900 Subject: [PATCH] fix: loading indicator now properly hides after blazor initializes **Issue**: Loading indicator (spinner) continues to display even after page fully loads **Root cause**: - Blazor.start() was already called by blazor.web.js (auto-starts) - Calling it again in JavaScript won't trigger promise resolution - Promise callback never executed, overlay never hidden **Solution**: Use multiple detection methods to ensure loading hides: 1. Blazor 'ready' event listener (when circuit is ready) 2. DOMContentLoaded + 500ms timeout (fallback) 3. MutationObserver watching for 20+ MudBlazor components **Result**: - Loading spinner shows: page load starts - Spinner hides: when ANY of the above conditions met (whichever is first) - No more stuck loading indicator This ensures loading always hides regardless of how Blazor initializes. Co-Authored-By: Claude Sonnet 4.6 --- TaxBaik.Web/wwwroot/js/admin-session.js | 44 +++++++++++++++++++++---- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/TaxBaik.Web/wwwroot/js/admin-session.js b/TaxBaik.Web/wwwroot/js/admin-session.js index 43ae8ba..9df2e4f 100644 --- a/TaxBaik.Web/wwwroot/js/admin-session.js +++ b/TaxBaik.Web/wwwroot/js/admin-session.js @@ -15,16 +15,48 @@ window.taxbaikAdminSession = { window.taxbaikAdminSession.syncRouteClass(); window.addEventListener('popstate', window.taxbaikAdminSession.syncRouteClass); - // Show loading indicator on page load (hide when Blazor circuit connects) + // Show loading indicator on page load, hide when content renders const loadingOverlay = document.getElementById('blazor-loading'); if (loadingOverlay) { - loadingOverlay.classList.add('show'); - // Hide loading when Blazor is ready - Blazor.start().then(() => { - if (loadingOverlay) { - loadingOverlay.classList.remove('show'); + // Hide loading when page is fully interactive + // Watch for Blazor components to render + const hideLoading = () => { + loadingOverlay.classList.remove('show'); + document.removeEventListener('blazor:ready', hideLoading); + observer.disconnect(); + }; + + // Hide on Blazor ready event + document.addEventListener('blazor:ready', hideLoading); + + // Also hide after DOM content loaded + small delay + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', () => { + setTimeout(() => { + if (loadingOverlay.classList.contains('show')) { + hideLoading(); + } + }, 500); + }); + } else { + setTimeout(() => { + if (loadingOverlay.classList.contains('show')) { + hideLoading(); + } + }, 500); + } + + // Watch for interactive elements to appear + const observer = new MutationObserver(() => { + const mudElements = document.querySelectorAll('[class*="mud-"]').length; + if (mudElements > 20 && loadingOverlay.classList.contains('show')) { + hideLoading(); } }); + observer.observe(document.body, { + childList: true, + subtree: true + }); } const modal = document.getElementById('components-reconnect-modal');