merge: sync with upstream/main and resolve conflicts
This commit is contained in:
@@ -34,7 +34,7 @@ document.addEventListener('alpine:init', () => {
|
|||||||
this.startAutoRefresh();
|
this.startAutoRefresh();
|
||||||
document.addEventListener('refresh-interval-changed', () => this.startAutoRefresh());
|
document.addEventListener('refresh-interval-changed', () => this.startAutoRefresh());
|
||||||
|
|
||||||
// Initial Fetch
|
// Initial Data Fetch (separate from health check)
|
||||||
Alpine.store('data').fetchData();
|
Alpine.store('data').fetchData();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ document.addEventListener('alpine:init', () => {
|
|||||||
initialLoad: true, // Track first load for skeleton screen
|
initialLoad: true, // Track first load for skeleton screen
|
||||||
connectionStatus: 'connecting',
|
connectionStatus: 'connecting',
|
||||||
lastUpdated: '-',
|
lastUpdated: '-',
|
||||||
|
healthCheckTimer: null,
|
||||||
|
|
||||||
// Filters state
|
// Filters state
|
||||||
filters: {
|
filters: {
|
||||||
@@ -39,6 +40,9 @@ document.addEventListener('alpine:init', () => {
|
|||||||
// Watch filters to recompute
|
// Watch filters to recompute
|
||||||
// Alpine stores don't have $watch automatically unless inside a component?
|
// Alpine stores don't have $watch automatically unless inside a component?
|
||||||
// We can manually call compute when filters change.
|
// We can manually call compute when filters change.
|
||||||
|
|
||||||
|
// Start health check monitoring
|
||||||
|
this.startHealthCheck();
|
||||||
},
|
},
|
||||||
|
|
||||||
loadFromCache() {
|
loadFromCache() {
|
||||||
@@ -111,7 +115,6 @@ document.addEventListener('alpine:init', () => {
|
|||||||
this.saveToCache(); // Save fresh data
|
this.saveToCache(); // Save fresh data
|
||||||
this.computeQuotaRows();
|
this.computeQuotaRows();
|
||||||
|
|
||||||
this.connectionStatus = 'connected';
|
|
||||||
this.lastUpdated = new Date().toLocaleTimeString();
|
this.lastUpdated = new Date().toLocaleTimeString();
|
||||||
|
|
||||||
// Fetch version from config endpoint if not already loaded
|
// Fetch version from config endpoint if not already loaded
|
||||||
@@ -120,7 +123,6 @@ document.addEventListener('alpine:init', () => {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Fetch error:', error);
|
console.error('Fetch error:', error);
|
||||||
this.connectionStatus = 'disconnected';
|
|
||||||
const store = Alpine.store('global');
|
const store = Alpine.store('global');
|
||||||
store.showToast(store.t('connectionLost'), 'error');
|
store.showToast(store.t('connectionLost'), 'error');
|
||||||
} finally {
|
} finally {
|
||||||
@@ -143,6 +145,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() {
|
computeQuotaRows() {
|
||||||
const models = this.models || [];
|
const models = this.models || [];
|
||||||
const rows = [];
|
const rows = [];
|
||||||
@@ -312,6 +375,13 @@ document.addEventListener('alpine:init', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return rows;
|
return rows;
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.stopHealthCheck();
|
||||||
|
if (this._visibilityHandler) {
|
||||||
|
document.removeEventListener('visibilitychange', this._visibilityHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user