feat: add mock mode

This commit is contained in:
2025-09-17 22:22:11 +02:00
parent bfe973afe6
commit 1062691e7b
15 changed files with 1964 additions and 456 deletions

View File

@@ -298,8 +298,8 @@ class ClusterMembersComponent extends Component {
// Update status
const statusElement = card.querySelector('.member-status');
if (statusElement) {
const statusClass = member.status === 'active' ? 'status-online' : 'status-offline';
const statusIcon = member.status === 'active' ? '🟢' : '🔴';
const statusClass = (member.status && member.status.toUpperCase() === 'ACTIVE') ? 'status-online' : 'status-offline';
const statusIcon = (member.status && member.status.toUpperCase() === 'ACTIVE') ? '🟢' : '🔴';
statusElement.className = `member-status ${statusClass}`;
statusElement.innerHTML = `${statusIcon}`;
@@ -402,9 +402,9 @@ class ClusterMembersComponent extends Component {
logger.debug('ClusterMembersComponent: renderMembers() called with', members.length, 'members');
const membersHTML = members.map(member => {
const statusClass = member.status === 'active' ? 'status-online' : 'status-offline';
const statusText = member.status === 'active' ? 'Online' : 'Offline';
const statusIcon = member.status === 'active' ? '🟢' : '🔴';
const statusClass = (member.status && member.status.toUpperCase() === 'ACTIVE') ? 'status-online' : 'status-offline';
const statusText = (member.status && member.status.toUpperCase() === 'ACTIVE') ? 'Online' : 'Offline';
const statusIcon = (member.status && member.status.toUpperCase() === 'ACTIVE') ? '🟢' : '🔴';
logger.debug('ClusterMembersComponent: Rendering member:', member);

View File

@@ -263,15 +263,18 @@ class NodeDetailsComponent extends Component {
if (monitoringResources.filesystem) {
const usedKB = Math.round(monitoringResources.filesystem.used_bytes / 1024);
const totalKB = Math.round(monitoringResources.filesystem.total_bytes / 1024);
const usagePercent = monitoringResources.filesystem.total_bytes > 0
? ((monitoringResources.filesystem.used_bytes / monitoringResources.filesystem.total_bytes) * 100).toFixed(1)
: '0.0';
html += `
<div class="detail-row">
<span class="detail-label">Filesystem:</span>
<span class="detail-value">${monitoringResources.filesystem.usage_percent ? monitoringResources.filesystem.usage_percent.toFixed(1) + '%' : 'N/A'} (${usedKB}KB / ${totalKB}KB)</span>
<span class="detail-value">${usagePercent}% (${usedKB}KB / ${totalKB}KB)</span>
</div>
`;
}
// System Uptime
// System Information
if (monitoringResources.system) {
html += `
<div class="detail-row">
@@ -281,6 +284,25 @@ class NodeDetailsComponent extends Component {
`;
}
// Network Information
if (monitoringResources.network) {
const uptimeSeconds = monitoringResources.network.uptime_seconds || 0;
const uptimeHours = Math.floor(uptimeSeconds / 3600);
const uptimeMinutes = Math.floor((uptimeSeconds % 3600) / 60);
const uptimeFormatted = `${uptimeHours}h ${uptimeMinutes}m`;
html += `
<div class="detail-row">
<span class="detail-label">WiFi RSSI:</span>
<span class="detail-value">${monitoringResources.network.wifi_rssi || 'N/A'} dBm</span>
</div>
<div class="detail-row">
<span class="detail-label">Network Uptime:</span>
<span class="detail-value">${uptimeFormatted}</span>
</div>
`;
}
html += `</div>`;
}
@@ -291,9 +313,9 @@ class NodeDetailsComponent extends Component {
// Get values with fallbacks and ensure they are numbers
const cpuUsage = parseFloat(monitoringResources.cpu?.average_usage) || 0;
const heapUsage = parseFloat(monitoringResources.memory?.heap_usage_percent) || 0;
const filesystemUsage = parseFloat(monitoringResources.filesystem?.usage_percent) || 0;
const filesystemUsed = parseFloat(monitoringResources.filesystem?.used_bytes) || 0;
const filesystemTotal = parseFloat(monitoringResources.filesystem?.total_bytes) || 0;
const filesystemUsage = filesystemTotal > 0 ? (filesystemUsed / filesystemTotal) * 100 : 0;
// Convert filesystem bytes to KB
const filesystemUsedKB = Math.round(filesystemUsed / 1024);

View File

@@ -831,10 +831,10 @@ class MemberCardOverlayComponent extends Component {
}
renderMemberCard(member) {
const statusClass = member.status === 'active' ? 'status-online' :
member.status === 'inactive' ? 'status-inactive' : 'status-offline';
const statusIcon = member.status === 'active' ? '🟢' :
member.status === 'inactive' ? '🟠' : '🔴';
const statusClass = (member.status && member.status.toUpperCase() === 'ACTIVE') ? 'status-online' :
(member.status && member.status.toUpperCase() === 'INACTIVE') ? 'status-inactive' : 'status-offline';
const statusIcon = (member.status && member.status.toUpperCase() === 'ACTIVE') ? '🟢' :
(member.status && member.status.toUpperCase() === 'INACTIVE') ? '🟠' : '🔴';
return `
<div class="member-overlay-content">

View File

@@ -42,7 +42,7 @@ class ClusterViewModel extends ViewModel {
const members = response.members || [];
const onlineNodes = Array.isArray(members)
? members.filter(m => m && m.status === 'active').length
? members.filter(m => m && m.status && m.status.toUpperCase() === 'ACTIVE').length
: 0;
// Use batch update to preserve UI state
@@ -281,7 +281,9 @@ class NodeDetailsViewModel extends ViewModel {
try {
const ip = this.get('nodeIp');
const response = await window.apiClient.getEndpoints(ip);
this.set('endpoints', response || null);
// Handle both real API (wrapped in endpoints) and mock API (direct array)
const endpointsData = (response && response.endpoints) ? response : { endpoints: response };
this.set('endpoints', endpointsData || null);
} catch (error) {
console.error('Failed to load endpoints:', error);
this.set('endpoints', null);
@@ -293,8 +295,8 @@ class NodeDetailsViewModel extends ViewModel {
try {
const ip = this.get('nodeIp');
const response = await window.apiClient.getMonitoringResources(ip);
// The proxy call returns { data: {...} }, so we need to extract the data
const monitoringData = (response && response.data) ? response.data : null;
// Handle both real API (wrapped in data) and mock API (direct response)
const monitoringData = (response && response.data) ? response.data : response;
this.set('monitoringResources', monitoringData);
} catch (error) {
console.error('Failed to load monitoring resources:', error);