Merge branch 'badrisnarayanan:main' into main
This commit is contained in:
@@ -82,10 +82,10 @@
|
||||
? 'bg-neon-green/10 border-neon-green/20 text-neon-green'
|
||||
: (connectionStatus === 'connecting' ? 'bg-yellow-500/10 border-yellow-500/20 text-yellow-500' : 'bg-red-500/10 border-red-500/20 text-red-500')">
|
||||
<div class="w-1.5 h-1.5 rounded-full"
|
||||
:class="connectionStatus === 'connected' ? 'bg-neon-green shadow-[0_0_8px_rgba(34,197,94,0.6)]' : (connectionStatus === 'connecting' ? 'bg-yellow-500 animate-pulse' : 'bg-red-500')">
|
||||
:class="$store.data.connectionStatus === 'connected' ? 'bg-neon-green shadow-[0_0_8px_rgba(34,197,94,0.6)]' : ($store.data.connectionStatus === 'connecting' ? 'bg-yellow-500 animate-pulse' : 'bg-red-500')">
|
||||
</div>
|
||||
<span
|
||||
x-text="$store.global.connectionStatus === 'connected' ? $store.global.t('online') : ($store.global.connectionStatus === 'disconnected' ? $store.global.t('offline') : $store.global.t('connecting'))"></span>
|
||||
x-text="$store.data.connectionStatus === 'connected' ? $store.global.t('online') : ($store.data.connectionStatus === 'connecting' ? $store.global.t('connecting') : $store.global.t('offline'))"></span>
|
||||
</div>
|
||||
|
||||
<div class="h-4 w-px bg-space-border"></div>
|
||||
|
||||
@@ -34,7 +34,7 @@ document.addEventListener('alpine:init', () => {
|
||||
this.startAutoRefresh();
|
||||
document.addEventListener('refresh-interval-changed', () => this.startAutoRefresh());
|
||||
|
||||
// Initial Fetch
|
||||
// Initial Data Fetch (separate from health check)
|
||||
Alpine.store('data').fetchData();
|
||||
},
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ document.addEventListener('alpine:init', () => {
|
||||
initialLoad: true, // Track first load for skeleton screen
|
||||
connectionStatus: 'connecting',
|
||||
lastUpdated: '-',
|
||||
healthCheckTimer: null,
|
||||
|
||||
// Filters state
|
||||
filters: {
|
||||
@@ -31,9 +32,8 @@ document.addEventListener('alpine:init', () => {
|
||||
// For simplicity, let's keep relevant filters here.
|
||||
|
||||
init() {
|
||||
// Watch filters to recompute
|
||||
// Alpine stores don't have $watch automatically unless inside a component?
|
||||
// We can manually call compute when filters change.
|
||||
// Start health check monitoring
|
||||
this.startHealthCheck();
|
||||
},
|
||||
|
||||
async fetchData() {
|
||||
@@ -67,7 +67,6 @@ document.addEventListener('alpine:init', () => {
|
||||
|
||||
this.computeQuotaRows();
|
||||
|
||||
this.connectionStatus = 'connected';
|
||||
this.lastUpdated = new Date().toLocaleTimeString();
|
||||
|
||||
// Fetch version from config endpoint if not already loaded
|
||||
@@ -76,7 +75,6 @@ document.addEventListener('alpine:init', () => {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fetch error:', error);
|
||||
this.connectionStatus = 'disconnected';
|
||||
const store = Alpine.store('global');
|
||||
store.showToast(store.t('connectionLost'), 'error');
|
||||
} finally {
|
||||
@@ -99,6 +97,67 @@ document.addEventListener('alpine:init', () => {
|
||||
}
|
||||
},
|
||||
|
||||
async performHealthCheck() {
|
||||
try {
|
||||
// Get password from global store
|
||||
const password = Alpine.store('global').webuiPassword;
|
||||
|
||||
// Use lightweight endpoint (no quota fetching)
|
||||
const { response, newPassword } = await window.utils.request('/api/config', {}, password);
|
||||
|
||||
if (newPassword) Alpine.store('global').webuiPassword = newPassword;
|
||||
|
||||
if (response.ok) {
|
||||
this.connectionStatus = 'connected';
|
||||
} else {
|
||||
this.connectionStatus = 'disconnected';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Health check error:', error);
|
||||
this.connectionStatus = 'disconnected';
|
||||
}
|
||||
},
|
||||
|
||||
startHealthCheck() {
|
||||
// Clear existing timer
|
||||
if (this.healthCheckTimer) {
|
||||
clearInterval(this.healthCheckTimer);
|
||||
}
|
||||
|
||||
// Setup visibility change listener (only once)
|
||||
if (!this._healthVisibilitySetup) {
|
||||
this._healthVisibilitySetup = true;
|
||||
this._visibilityHandler = () => {
|
||||
if (document.hidden) {
|
||||
// Tab hidden - stop health checks
|
||||
this.stopHealthCheck();
|
||||
} else {
|
||||
// Tab visible - restart health checks
|
||||
this.startHealthCheck();
|
||||
}
|
||||
};
|
||||
document.addEventListener('visibilitychange', this._visibilityHandler);
|
||||
}
|
||||
|
||||
// Perform immediate health check
|
||||
this.performHealthCheck();
|
||||
|
||||
// Schedule regular health checks every 15 seconds
|
||||
this.healthCheckTimer = setInterval(() => {
|
||||
// Only perform health check if tab is visible
|
||||
if (!document.hidden) {
|
||||
this.performHealthCheck();
|
||||
}
|
||||
}, 15000);
|
||||
},
|
||||
|
||||
stopHealthCheck() {
|
||||
if (this.healthCheckTimer) {
|
||||
clearInterval(this.healthCheckTimer);
|
||||
this.healthCheckTimer = null;
|
||||
}
|
||||
},
|
||||
|
||||
computeQuotaRows() {
|
||||
const models = this.models || [];
|
||||
const rows = [];
|
||||
@@ -233,6 +292,13 @@ document.addEventListener('alpine:init', () => {
|
||||
});
|
||||
|
||||
return rows;
|
||||
},
|
||||
|
||||
destroy() {
|
||||
this.stopHealthCheck();
|
||||
if (this._visibilityHandler) {
|
||||
document.removeEventListener('visibilitychange', this._visibilityHandler);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user