mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-28 03:20:11 +00:00
fix(ai): fix mention status colors and dedup for docker/VM/LXC agents (#1252)
Three fixes for remaining mention autocomplete issues: - Status dots now correctly show green/red/yellow for online/offline/ degraded statuses (previously only handled running/stopped/paused) - Docker hosts merge with their host agent via agentId cross-reference - VMs and LXC containers merge with host agents running inside them via linkedVmId/linkedContainerId backend ID aliases
This commit is contained in:
parent
06bd8cf2b6
commit
50e476c942
3 changed files with 139 additions and 10 deletions
|
|
@ -110,12 +110,20 @@ export function MentionAutocomplete(props: MentionAutocompleteProps) {
|
|||
|
||||
// Get status color
|
||||
const getStatusColor = (status?: string) => {
|
||||
switch (status) {
|
||||
switch (status?.toLowerCase()) {
|
||||
case 'running':
|
||||
case 'online':
|
||||
case 'healthy':
|
||||
case 'up':
|
||||
return 'bg-green-500';
|
||||
case 'stopped':
|
||||
case 'offline':
|
||||
case 'error':
|
||||
case 'failed':
|
||||
return 'bg-red-500';
|
||||
case 'paused':
|
||||
case 'degraded':
|
||||
case 'warning':
|
||||
return 'bg-yellow-500';
|
||||
default:
|
||||
return 'bg-gray-400';
|
||||
|
|
|
|||
|
|
@ -113,6 +113,109 @@ describe('mentionResources', () => {
|
|||
expect(nodeOrHost[0].name).toBe('pve01');
|
||||
});
|
||||
|
||||
it('deduplicates docker host and host agent via agentId (#1252)', () => {
|
||||
// Docker host has agentId matching the host agent's id
|
||||
const state = {
|
||||
nodes: [],
|
||||
vms: [],
|
||||
containers: [],
|
||||
dockerHosts: [
|
||||
{
|
||||
id: 'docker-host-abc',
|
||||
agentId: 'agent-xyz',
|
||||
hostname: 'docker01',
|
||||
displayName: 'docker01',
|
||||
status: 'online',
|
||||
lastSeen: Date.now(),
|
||||
containers: [],
|
||||
},
|
||||
],
|
||||
hosts: [
|
||||
{
|
||||
id: 'agent-xyz',
|
||||
hostname: 'docker01',
|
||||
displayName: 'docker01',
|
||||
status: 'online',
|
||||
lastSeen: Date.now(),
|
||||
memory: { total: 16, used: 8, free: 8, usage: 50 },
|
||||
},
|
||||
],
|
||||
} as unknown as State;
|
||||
|
||||
const resources = buildMentionResources(state);
|
||||
const hostEntries = resources.filter((r) => r.type === 'host');
|
||||
expect(hostEntries).toHaveLength(1);
|
||||
expect(hostEntries[0].name).toBe('docker01');
|
||||
});
|
||||
|
||||
it('deduplicates VM and host agent running inside it via linkedVmId (#1252)', () => {
|
||||
const state = {
|
||||
nodes: [],
|
||||
vms: [
|
||||
{
|
||||
id: 'pve01-100',
|
||||
vmid: 100,
|
||||
name: 'my-vm',
|
||||
node: 'pve01',
|
||||
instance: 'pve-instance-1',
|
||||
status: 'running',
|
||||
},
|
||||
],
|
||||
containers: [],
|
||||
dockerHosts: [],
|
||||
hosts: [
|
||||
{
|
||||
id: 'agent-in-vm',
|
||||
hostname: 'my-vm',
|
||||
displayName: 'my-vm',
|
||||
status: 'online',
|
||||
lastSeen: Date.now(),
|
||||
linkedVmId: 'pve01-100',
|
||||
memory: { total: 8, used: 4, free: 4, usage: 50 },
|
||||
},
|
||||
],
|
||||
} as unknown as State;
|
||||
|
||||
const resources = buildMentionResources(state);
|
||||
const vmOrHost = resources.filter((r) => r.type === 'vm' || r.type === 'host');
|
||||
expect(vmOrHost).toHaveLength(1);
|
||||
expect(vmOrHost[0].name).toBe('my-vm');
|
||||
});
|
||||
|
||||
it('deduplicates LXC container and host agent running inside it via linkedContainerId (#1252)', () => {
|
||||
const state = {
|
||||
nodes: [],
|
||||
vms: [],
|
||||
containers: [
|
||||
{
|
||||
id: 'pve01-200',
|
||||
vmid: 200,
|
||||
name: 'my-ct',
|
||||
node: 'pve01',
|
||||
instance: 'pve-instance-1',
|
||||
status: 'running',
|
||||
},
|
||||
],
|
||||
dockerHosts: [],
|
||||
hosts: [
|
||||
{
|
||||
id: 'agent-in-ct',
|
||||
hostname: 'my-ct',
|
||||
displayName: 'my-ct',
|
||||
status: 'online',
|
||||
lastSeen: Date.now(),
|
||||
linkedContainerId: 'pve01-200',
|
||||
memory: { total: 4, used: 2, free: 2, usage: 50 },
|
||||
},
|
||||
],
|
||||
} as unknown as State;
|
||||
|
||||
const resources = buildMentionResources(state);
|
||||
const ctOrHost = resources.filter((r) => r.type === 'container' || r.type === 'host');
|
||||
expect(ctOrHost).toHaveLength(1);
|
||||
expect(ctOrHost[0].name).toBe('my-ct');
|
||||
});
|
||||
|
||||
it('deduplicates cluster node mentions from multiple instances and keeps the healthiest status', () => {
|
||||
const state = {
|
||||
nodes: [
|
||||
|
|
|
|||
|
|
@ -138,7 +138,11 @@ export function buildMentionResources(state: MentionStateSubset): MentionResourc
|
|||
status: vm.status,
|
||||
node: vm.node,
|
||||
},
|
||||
[`vm-id:${vm.node}:${vm.vmid}`],
|
||||
[
|
||||
`vm-id:${vm.node}:${vm.vmid}`,
|
||||
// Register backend VM ID so host agents with linkedVmId can merge (#1252)
|
||||
`vm-backend-id:${vm.id}`,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -153,12 +157,25 @@ export function buildMentionResources(state: MentionStateSubset): MentionResourc
|
|||
status: container.status,
|
||||
node: container.node,
|
||||
},
|
||||
[`lxc-id:${container.node}:${container.vmid}`],
|
||||
[
|
||||
`lxc-id:${container.node}:${container.vmid}`,
|
||||
// Register backend container ID so host agents with linkedContainerId can merge (#1252)
|
||||
`lxc-backend-id:${container.id}`,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
for (const host of state.dockerHosts || []) {
|
||||
const hostName = host.displayName || host.hostname || host.id;
|
||||
const dockerAliases = [
|
||||
`docker-host-id:${host.id}`,
|
||||
`host-name:${hostName}`,
|
||||
`host-hostname:${host.hostname}`,
|
||||
];
|
||||
// Link docker host to its host agent via agentId so they merge (#1252)
|
||||
if (host.agentId) {
|
||||
dockerAliases.push(`agent-host-id:${host.agentId}`);
|
||||
}
|
||||
upsertMentionResource(
|
||||
byKey,
|
||||
aliasToKey,
|
||||
|
|
@ -168,11 +185,7 @@ export function buildMentionResources(state: MentionStateSubset): MentionResourc
|
|||
type: 'host',
|
||||
status: host.status || 'online',
|
||||
},
|
||||
[
|
||||
`docker-host-id:${host.id}`,
|
||||
`host-name:${hostName}`,
|
||||
`host-hostname:${host.hostname}`,
|
||||
],
|
||||
dockerAliases,
|
||||
);
|
||||
|
||||
for (const container of host.containers || []) {
|
||||
|
|
@ -223,11 +236,16 @@ export function buildMentionResources(state: MentionStateSubset): MentionResourc
|
|||
`host-name:${hostName}`,
|
||||
`host-hostname:${host.hostname}`,
|
||||
];
|
||||
// If this host agent is linked to a PVE node, add the node's backend ID alias so they merge (#1252).
|
||||
// linkedNodeId is the node's backend ID (format: "instance-nodeName").
|
||||
// If this host agent is linked to a PVE entity, add its backend ID alias so they merge (#1252).
|
||||
if (host.linkedNodeId) {
|
||||
aliases.push(`node-backend-id:${host.linkedNodeId}`);
|
||||
}
|
||||
if (host.linkedVmId) {
|
||||
aliases.push(`vm-backend-id:${host.linkedVmId}`);
|
||||
}
|
||||
if (host.linkedContainerId) {
|
||||
aliases.push(`lxc-backend-id:${host.linkedContainerId}`);
|
||||
}
|
||||
upsertMentionResource(
|
||||
byKey,
|
||||
aliasToKey,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue