Merge pull request #188 from quocthai0404/fix/issue-183-console-warnings-ui
fix: Reduce console warnings and errors in web UI (#183)
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
|
||||
<body
|
||||
class="bg-space-950 text-gray-300 font-sans antialiased min-h-screen overflow-hidden selection:bg-neon-purple selection:text-white"
|
||||
x-cloak x-data="app" x-init="console.log('App initialized')">
|
||||
x-cloak x-data="app" x-init="if(window.UILogger) window.UILogger.debug('App initialized')">
|
||||
|
||||
<!-- Toast Notification -->
|
||||
<div class="fixed top-4 right-4 z-[100] flex flex-col gap-2 pointer-events-none">
|
||||
@@ -389,6 +389,7 @@
|
||||
<!-- Scripts - Loading Order Matters! -->
|
||||
<!-- 1. Config & Utils (global helpers) -->
|
||||
<script src="js/config/constants.js"></script>
|
||||
<script src="js/utils/ui-logger.js"></script><!-- Issue #183: Conditional logging utility -->
|
||||
<script src="js/utils.js"></script>
|
||||
<script src="js/utils/error-handler.js"></script>
|
||||
<script src="js/utils/account-actions.js"></script>
|
||||
|
||||
@@ -106,7 +106,7 @@ window.DashboardCharts.createDataset = function (label, data, color, canvas) {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("Failed to create gradient, using solid color fallback:", e);
|
||||
if (window.UILogger) window.UILogger.debug("Gradient fallback:", e.message);
|
||||
gradient = null;
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ window.DashboardCharts.updateCharts = function (component) {
|
||||
console.debug("Destroying existing quota chart from canvas property");
|
||||
try {
|
||||
canvas._chartInstance.destroy();
|
||||
} catch(e) { console.warn(e); }
|
||||
} catch(e) { if (window.UILogger) window.UILogger.debug(e); }
|
||||
canvas._chartInstance = null;
|
||||
}
|
||||
|
||||
@@ -170,11 +170,11 @@ window.DashboardCharts.updateCharts = function (component) {
|
||||
}
|
||||
|
||||
if (typeof Chart === "undefined") {
|
||||
console.warn("Chart.js not loaded");
|
||||
if (window.UILogger) window.UILogger.warn("Chart.js not loaded");
|
||||
return;
|
||||
}
|
||||
if (!isCanvasReady(canvas)) {
|
||||
console.debug("quotaChart canvas not ready, skipping update");
|
||||
if (window.UILogger) window.UILogger.debug("quotaChart canvas not ready, skipping update");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -319,12 +319,13 @@ window.DashboardCharts.updateCharts = function (component) {
|
||||
window.DashboardCharts.updateTrendChart = function (component) {
|
||||
// Prevent concurrent updates (fixes race condition on rapid toggling)
|
||||
if (_trendChartUpdateLock) {
|
||||
console.log("[updateTrendChart] Update already in progress, skipping");
|
||||
if (window.UILogger) window.UILogger.debug("[updateTrendChart] Update already in progress, skipping");
|
||||
return;
|
||||
}
|
||||
_trendChartUpdateLock = true;
|
||||
|
||||
console.log("[updateTrendChart] Starting update...");
|
||||
const logger = window.UILogger || console;
|
||||
logger.debug("[updateTrendChart] Starting update...");
|
||||
|
||||
const canvas = document.getElementById("usageTrendChart");
|
||||
|
||||
@@ -335,7 +336,7 @@ window.DashboardCharts.updateTrendChart = function (component) {
|
||||
try {
|
||||
canvas._chartInstance.stop();
|
||||
canvas._chartInstance.destroy();
|
||||
} catch(e) { console.warn(e); }
|
||||
} catch(e) { if (window.UILogger) window.UILogger.debug(e); }
|
||||
canvas._chartInstance = null;
|
||||
}
|
||||
|
||||
@@ -359,17 +360,17 @@ window.DashboardCharts.updateTrendChart = function (component) {
|
||||
|
||||
// Safety checks
|
||||
if (!canvas) {
|
||||
console.error("[updateTrendChart] Canvas not found in DOM!");
|
||||
_trendChartUpdateLock = false; // Release lock!
|
||||
if (window.UILogger) window.UILogger.debug("[updateTrendChart] Canvas not found in DOM");
|
||||
_trendChartUpdateLock = false;
|
||||
return;
|
||||
}
|
||||
if (typeof Chart === "undefined") {
|
||||
console.error("[updateTrendChart] Chart.js not loaded");
|
||||
_trendChartUpdateLock = false; // Release lock!
|
||||
if (window.UILogger) window.UILogger.warn("[updateTrendChart] Chart.js not loaded");
|
||||
_trendChartUpdateLock = false;
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("[updateTrendChart] Canvas element:", {
|
||||
if (window.UILogger) window.UILogger.debug("[updateTrendChart] Canvas element:", {
|
||||
exists: !!canvas,
|
||||
isConnected: canvas.isConnected,
|
||||
width: canvas.offsetWidth,
|
||||
@@ -378,7 +379,7 @@ window.DashboardCharts.updateTrendChart = function (component) {
|
||||
});
|
||||
|
||||
if (!isCanvasReady(canvas)) {
|
||||
console.error("[updateTrendChart] Canvas not ready!", {
|
||||
if (window.UILogger) window.UILogger.debug("[updateTrendChart] Canvas not ready", {
|
||||
isConnected: canvas.isConnected,
|
||||
width: canvas.offsetWidth,
|
||||
height: canvas.offsetHeight,
|
||||
@@ -394,17 +395,17 @@ window.DashboardCharts.updateTrendChart = function (component) {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("[updateTrendChart] Failed to clear canvas:", e);
|
||||
if (window.UILogger) window.UILogger.debug("[updateTrendChart] Failed to clear canvas:", e.message);
|
||||
}
|
||||
|
||||
console.log(
|
||||
if (window.UILogger) window.UILogger.debug(
|
||||
"[updateTrendChart] Canvas is ready, proceeding with chart creation"
|
||||
);
|
||||
|
||||
// Use filtered history data based on time range
|
||||
const history = window.DashboardFilters.getFilteredHistoryData(component);
|
||||
if (!history || Object.keys(history).length === 0) {
|
||||
console.warn("No history data available for trend chart (after filtering)");
|
||||
if (window.UILogger) window.UILogger.debug("No history data available for trend chart (after filtering)");
|
||||
component.hasFilteredTrendData = false;
|
||||
_trendChartUpdateLock = false;
|
||||
return;
|
||||
|
||||
@@ -50,7 +50,7 @@ window.DashboardFilters.loadPreferences = function(component) {
|
||||
component.selectedModels = prefs.selectedModels || {};
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to load dashboard preferences:', e);
|
||||
if (window.UILogger) window.UILogger.debug('Failed to load dashboard preferences:', e.message);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -67,7 +67,7 @@ window.DashboardFilters.savePreferences = function(component) {
|
||||
selectedModels: component.selectedModels
|
||||
}));
|
||||
} catch (e) {
|
||||
console.error('Failed to save dashboard preferences:', e);
|
||||
if (window.UILogger) window.UILogger.debug('Failed to save dashboard preferences:', e.message);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -79,12 +79,12 @@ window.Components.logsViewer = () => ({
|
||||
this.$nextTick(() => this.scrollToBottom());
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Log parse error:', e);
|
||||
if (window.UILogger) window.UILogger.debug('Log parse error:', e.message);
|
||||
}
|
||||
};
|
||||
|
||||
this.eventSource.onerror = () => {
|
||||
console.warn('Log stream disconnected, reconnecting...');
|
||||
if (window.UILogger) window.UILogger.debug('Log stream disconnected, reconnecting...');
|
||||
setTimeout(() => this.startLogStream(), 3000);
|
||||
};
|
||||
},
|
||||
|
||||
@@ -55,7 +55,7 @@ document.addEventListener('alpine:init', () => {
|
||||
|
||||
// Check TTL
|
||||
if (data.timestamp && (Date.now() - data.timestamp > CACHE_TTL)) {
|
||||
console.log('Cache expired, skipping restoration');
|
||||
if (window.UILogger) window.UILogger.debug('Cache expired, skipping restoration');
|
||||
localStorage.removeItem('ag_data_cache');
|
||||
return;
|
||||
}
|
||||
@@ -70,11 +70,11 @@ document.addEventListener('alpine:init', () => {
|
||||
// Don't show loading on initial load if we have cache
|
||||
this.initialLoad = false;
|
||||
this.computeQuotaRows();
|
||||
console.log('Restored data from cache');
|
||||
if (window.UILogger) window.UILogger.debug('Restored data from cache');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Failed to load cache', e);
|
||||
if (window.UILogger) window.UILogger.debug('Failed to load cache', e.message);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -89,7 +89,7 @@ document.addEventListener('alpine:init', () => {
|
||||
};
|
||||
localStorage.setItem('ag_data_cache', JSON.stringify(cacheData));
|
||||
} catch (e) {
|
||||
console.warn('Failed to save cache', e);
|
||||
if (window.UILogger) window.UILogger.debug('Failed to save cache', e.message);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -127,6 +127,7 @@ document.addEventListener('alpine:init', () => {
|
||||
|
||||
this.lastUpdated = new Date().toLocaleTimeString();
|
||||
} catch (error) {
|
||||
// Keep error logging for actual fetch failures
|
||||
console.error('Fetch error:', error);
|
||||
const store = Alpine.store('global');
|
||||
store.showToast(store.t('connectionLost'), 'error');
|
||||
|
||||
143
public/js/utils/ui-logger.js
Normal file
143
public/js/utils/ui-logger.js
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* UI Logger Utility
|
||||
* Provides conditional logging for the web UI to reduce console spam in production.
|
||||
* Wraps console methods and only outputs when debug mode is enabled.
|
||||
*
|
||||
* Usage:
|
||||
* window.UILogger.debug('message') - Only logs if debug mode enabled
|
||||
* window.UILogger.info('message') - Only logs if debug mode enabled
|
||||
* window.UILogger.warn('message') - Always logs (important warnings)
|
||||
* window.UILogger.error('message') - Always logs (errors should always be visible)
|
||||
*
|
||||
* Enable debug mode:
|
||||
* - Set localStorage.setItem('ag_debug', 'true') in browser console
|
||||
* - Or pass ?debug=true in URL
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// Check if debug mode is enabled
|
||||
function isDebugEnabled() {
|
||||
// Check URL parameter
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.get('debug') === 'true') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check localStorage
|
||||
try {
|
||||
return localStorage.getItem('ag_debug') === 'true';
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache debug state (can be refreshed)
|
||||
let debugEnabled = isDebugEnabled();
|
||||
|
||||
window.UILogger = {
|
||||
/**
|
||||
* Refresh debug state (call after changing localStorage)
|
||||
*/
|
||||
refresh() {
|
||||
debugEnabled = isDebugEnabled();
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable debug mode
|
||||
*/
|
||||
enableDebug() {
|
||||
try {
|
||||
localStorage.setItem('ag_debug', 'true');
|
||||
debugEnabled = true;
|
||||
console.info('[UILogger] Debug mode enabled. Refresh page to see all logs.');
|
||||
} catch (e) {
|
||||
console.warn('[UILogger] Could not save debug preference');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Disable debug mode
|
||||
*/
|
||||
disableDebug() {
|
||||
try {
|
||||
localStorage.removeItem('ag_debug');
|
||||
debugEnabled = false;
|
||||
console.info('[UILogger] Debug mode disabled.');
|
||||
} catch (e) {
|
||||
// Ignore
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if debug mode is enabled
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isDebug() {
|
||||
return debugEnabled;
|
||||
},
|
||||
|
||||
/**
|
||||
* Debug level - only logs if debug mode enabled
|
||||
* Use for verbose debugging info (chart updates, cache operations, etc.)
|
||||
*/
|
||||
debug(...args) {
|
||||
if (debugEnabled) {
|
||||
console.log('[DEBUG]', ...args);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Info level - only logs if debug mode enabled
|
||||
* Use for informational messages that aren't errors
|
||||
*/
|
||||
info(...args) {
|
||||
if (debugEnabled) {
|
||||
console.info('[INFO]', ...args);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Log level - alias for debug
|
||||
*/
|
||||
log(...args) {
|
||||
if (debugEnabled) {
|
||||
console.log(...args);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Warn level - always logs
|
||||
* Use for important warnings that users should see
|
||||
* But suppress noisy/expected warnings unless in debug mode
|
||||
*/
|
||||
warn(...args) {
|
||||
// In production, only show critical warnings
|
||||
// In debug mode, show all warnings
|
||||
if (debugEnabled) {
|
||||
console.warn(...args);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Warn level that always shows (for critical warnings)
|
||||
*/
|
||||
warnAlways(...args) {
|
||||
console.warn(...args);
|
||||
},
|
||||
|
||||
/**
|
||||
* Error level - always logs
|
||||
* Errors should always be visible for debugging
|
||||
*/
|
||||
error(...args) {
|
||||
console.error(...args);
|
||||
}
|
||||
};
|
||||
|
||||
// Log initial state (only in debug mode)
|
||||
if (debugEnabled) {
|
||||
console.info('[UILogger] Debug mode is ON. Set localStorage ag_debug=false to disable.');
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user