Files
spore-ui/public/scripts/components/ClusterStatusComponent.js
2025-10-14 21:41:15 +02:00

113 lines
4.4 KiB
JavaScript

// Cluster Status Component for header badge
class ClusterStatusComponent extends Component {
constructor(container, viewModel, eventBus) {
super(container, viewModel, eventBus);
this.wsConnected = false;
this.wsReconnectAttempts = 0;
}
setupViewModelListeners() {
// Subscribe to properties that affect cluster status
this.subscribeToProperty('totalNodes', this.render.bind(this));
this.subscribeToProperty('clientInitialized', this.render.bind(this));
this.subscribeToProperty('error', this.render.bind(this));
// Set up WebSocket status listeners
this.setupWebSocketListeners();
}
setupWebSocketListeners() {
if (!window.wsClient) return;
window.wsClient.on('connected', () => {
this.wsConnected = true;
this.wsReconnectAttempts = 0;
this.render();
});
window.wsClient.on('disconnected', () => {
this.wsConnected = false;
this.render();
});
window.wsClient.on('maxReconnectAttemptsReached', () => {
this.wsConnected = false;
this.wsReconnectAttempts = window.wsClient ? window.wsClient.reconnectAttempts : 0;
this.render();
});
// Initialize current WebSocket status
if (window.wsClient) {
const status = window.wsClient.getConnectionStatus();
this.wsConnected = status.connected;
this.wsReconnectAttempts = status.reconnectAttempts;
}
}
render() {
const totalNodes = this.viewModel.get('totalNodes');
const clientInitialized = this.viewModel.get('clientInitialized');
const error = this.viewModel.get('error');
let statusText, statusIcon, statusClass;
let wsStatusText = '';
let wsStatusIcon = '';
// Determine WebSocket status
if (this.wsConnected) {
wsStatusIcon = window.icon('dotGreen', { width: 10, height: 10 });
wsStatusText = 'Live';
} else if (this.wsReconnectAttempts > 0) {
wsStatusIcon = window.icon('dotYellow', { width: 10, height: 10 });
wsStatusText = 'Reconnecting';
} else {
wsStatusIcon = window.icon('dotRed', { width: 10, height: 10 });
wsStatusText = 'Offline';
}
if (error) {
statusText = 'Cluster Error';
statusIcon = window.icon('error', { width: 12, height: 12 });
statusClass = 'cluster-status-error';
} else if (totalNodes === 0) {
statusText = 'Cluster Offline';
statusIcon = window.icon('dotRed', { width: 12, height: 12 });
statusClass = 'cluster-status-offline';
} else if (clientInitialized) {
statusText = 'Cluster Online';
statusIcon = window.icon('dotGreen', { width: 12, height: 12 });
statusClass = 'cluster-status-online';
} else {
statusText = 'Cluster Connecting';
statusIcon = window.icon('dotYellow', { width: 12, height: 12 });
statusClass = 'cluster-status-connecting';
}
// Update the cluster status badge using the container passed to this component
if (this.container) {
// Create HTML with both cluster and WebSocket status on a single compact line
this.container.innerHTML = `
<div class="cluster-status-compact">
<span class="cluster-status-main">${statusIcon} ${statusText}</span>
<span class="websocket-status" title="WebSocket Connection: ${wsStatusText}">${wsStatusIcon} ${wsStatusText}</span>
</div>
`;
// Remove all existing status classes
this.container.classList.remove('cluster-status-online', 'cluster-status-offline', 'cluster-status-connecting', 'cluster-status-error');
// Add the appropriate status class
this.container.classList.add(statusClass);
// Add WebSocket connection class
this.container.classList.remove('ws-connected', 'ws-disconnected', 'ws-reconnecting');
if (this.wsConnected) {
this.container.classList.add('ws-connected');
} else if (this.wsReconnectAttempts > 0) {
this.container.classList.add('ws-reconnecting');
} else {
this.container.classList.add('ws-disconnected');
}
}
}
}