mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-13 15:28:38 +00:00
fix: tag indicators now only show for guests that actually have tags
- Added ToFrontend() method to StateSnapshot for proper data conversion - Modified /api/state endpoint to use frontend-formatted data - Enhanced WebSocket store to handle tag data transformation consistently - Ensures tags are properly converted between backend strings and frontend arrays
This commit is contained in:
parent
426f4b274e
commit
21d784164a
3 changed files with 95 additions and 3 deletions
|
|
@ -99,8 +99,58 @@ export function createWebSocketStore(url: string) {
|
|||
console.log('[WebSocket] Updating nodes:', message.data.nodes?.length || 0);
|
||||
setState('nodes', message.data.nodes);
|
||||
}
|
||||
if (message.data.vms !== undefined) setState('vms', message.data.vms);
|
||||
if (message.data.containers !== undefined) setState('containers', message.data.containers);
|
||||
if (message.data.vms !== undefined) {
|
||||
// Transform tags from comma-separated strings to arrays
|
||||
const transformedVMs = message.data.vms.map((vm: any) => {
|
||||
const originalTags = vm.tags;
|
||||
let transformedTags;
|
||||
|
||||
if (originalTags && typeof originalTags === 'string' && originalTags.trim()) {
|
||||
// String with content - split into array
|
||||
transformedTags = originalTags.split(',').map((t: string) => t.trim()).filter((t: string) => t.length > 0);
|
||||
} else if (Array.isArray(originalTags)) {
|
||||
// Already an array - filter out empty/whitespace-only tags
|
||||
transformedTags = originalTags.filter((tag: any) =>
|
||||
typeof tag === 'string' && tag.trim().length > 0
|
||||
);
|
||||
} else {
|
||||
// null, undefined, empty string, or other - convert to empty array
|
||||
transformedTags = [];
|
||||
}
|
||||
|
||||
return {
|
||||
...vm,
|
||||
tags: transformedTags
|
||||
};
|
||||
});
|
||||
setState('vms', transformedVMs);
|
||||
}
|
||||
if (message.data.containers !== undefined) {
|
||||
// Transform tags from comma-separated strings to arrays
|
||||
const transformedContainers = message.data.containers.map((container: any) => {
|
||||
const originalTags = container.tags;
|
||||
let transformedTags;
|
||||
|
||||
if (originalTags && typeof originalTags === 'string' && originalTags.trim()) {
|
||||
// String with content - split into array
|
||||
transformedTags = originalTags.split(',').map((t: string) => t.trim()).filter((t: string) => t.length > 0);
|
||||
} else if (Array.isArray(originalTags)) {
|
||||
// Already an array - filter out empty/whitespace-only tags
|
||||
transformedTags = originalTags.filter((tag: any) =>
|
||||
typeof tag === 'string' && tag.trim().length > 0
|
||||
);
|
||||
} else {
|
||||
// null, undefined, empty string, or other - convert to empty array
|
||||
transformedTags = [];
|
||||
}
|
||||
|
||||
return {
|
||||
...container,
|
||||
tags: transformedTags
|
||||
};
|
||||
});
|
||||
setState('containers', transformedContainers);
|
||||
}
|
||||
if (message.data.storage !== undefined) setState('storage', message.data.storage);
|
||||
if (message.data.pbs !== undefined) setState('pbs', message.data.pbs);
|
||||
if (message.data.pbsBackups !== undefined) setState('pbsBackups', message.data.pbsBackups);
|
||||
|
|
|
|||
|
|
@ -1513,8 +1513,9 @@ func (r *Router) handleState(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
state := r.monitor.GetState()
|
||||
frontendState := state.ToFrontend()
|
||||
|
||||
if err := utils.WriteJSONResponse(w, state); err != nil {
|
||||
if err := utils.WriteJSONResponse(w, frontendState); err != nil {
|
||||
log.Error().Err(err).Msg("Failed to encode state response")
|
||||
writeErrorResponse(w, http.StatusInternalServerError, "encoding_error",
|
||||
"Failed to encode state data", nil)
|
||||
|
|
|
|||
|
|
@ -53,4 +53,45 @@ func (s *State) GetSnapshot() StateSnapshot {
|
|||
}
|
||||
|
||||
return snapshot
|
||||
}
|
||||
|
||||
// ToFrontend converts a StateSnapshot to frontend format with proper tag handling
|
||||
func (s StateSnapshot) ToFrontend() StateFrontend {
|
||||
// Convert nodes
|
||||
nodes := make([]NodeFrontend, len(s.Nodes))
|
||||
for i, n := range s.Nodes {
|
||||
nodes[i] = n.ToFrontend()
|
||||
}
|
||||
|
||||
// Convert VMs
|
||||
vms := make([]VMFrontend, len(s.VMs))
|
||||
for i, v := range s.VMs {
|
||||
vms[i] = v.ToFrontend()
|
||||
}
|
||||
|
||||
// Convert containers
|
||||
containers := make([]ContainerFrontend, len(s.Containers))
|
||||
for i, c := range s.Containers {
|
||||
containers[i] = c.ToFrontend()
|
||||
}
|
||||
|
||||
// Convert storage
|
||||
storage := make([]StorageFrontend, len(s.Storage))
|
||||
for i, st := range s.Storage {
|
||||
storage[i] = st.ToFrontend()
|
||||
}
|
||||
|
||||
return StateFrontend{
|
||||
Nodes: nodes,
|
||||
VMs: vms,
|
||||
Containers: containers,
|
||||
Storage: storage,
|
||||
PBS: s.PBSInstances,
|
||||
Metrics: make(map[string]any),
|
||||
PVEBackups: s.PVEBackups,
|
||||
Performance: make(map[string]any),
|
||||
ConnectionHealth: s.ConnectionHealth,
|
||||
Stats: make(map[string]any),
|
||||
LastUpdate: s.LastUpdate.Unix() * 1000, // JavaScript timestamp
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue