Files
taxbaik/TaxBaik.Web/wwwroot/js/admin-session.js
T
kjh2064 79d99cfd7a
TaxBaik CI/CD / build-and-deploy (push) Successful in 1m23s
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 <noreply@anthropic.com>
2026-06-28 15:02:57 +09:00

79 lines
2.9 KiB
JavaScript

window.taxbaikAdminSession = {
syncRouteClass: function () {
document.documentElement.classList.toggle(
'admin-login-route',
window.location.pathname.toLowerCase().endsWith('/admin/login'));
},
clearAuthToken: function () {
try {
localStorage.removeItem('auth_token');
} catch {
// Ignore storage errors; redirect still recovers the session.
}
},
watchReconnect: function () {
window.taxbaikAdminSession.syncRouteClass();
window.addEventListener('popstate', window.taxbaikAdminSession.syncRouteClass);
// Show loading indicator on page load, hide when content renders
const loadingOverlay = document.getElementById('blazor-loading');
if (loadingOverlay) {
// 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');
if (!modal) {
return;
}
const reloadOnRejectedCircuit = () => {
const className = modal.className || '';
if (className.includes('components-reconnect-failed') ||
className.includes('components-reconnect-rejected')) {
window.setTimeout(() => window.location.reload(), 1500);
}
};
new MutationObserver(reloadOnRejectedCircuit)
.observe(modal, { attributes: true, attributeFilter: ['class'] });
}
};