mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-11 14:00:29 +00:00
Subscribe workloads guest metadata to the canonical metadata event
The workloads metadata state still listened for the legacy pulse:metadata-changed event, which no code dispatches since URL saves moved to dispatchResourceMetadataChanged, and its handler rewrote 3-part canonical guest ids into the v5-era instance-vmid shape that no lookup uses. In-page saves only stayed live through the drawer's direct callback; any other dispatcher was invisible. Listen for pulse:resource-metadata-changed and apply updates under the dispatched metadata id, ignoring agent-kind events that never key workload rows. Refs #1556 Contract-Neutral: behavioral fix: workloads metadata state listened for a legacy event nothing dispatches; no public contract change (#1556)
This commit is contained in:
+1
-1
@@ -1041,7 +1041,7 @@ describe('Workloads performance contract', () => {
|
||||
expect(workloadsGuestMetadataStateSource).toContain('GuestMetadataAPI.getAllMetadata()');
|
||||
expect(workloadsGuestMetadataStateSource).toContain("eventBus.on('org_switched'");
|
||||
expect(workloadsGuestMetadataStateSource).toContain(
|
||||
"window.addEventListener('pulse:metadata-changed'",
|
||||
'window.addEventListener(RESOURCE_METADATA_CHANGED_EVENT',
|
||||
);
|
||||
expect(workloadsWorkloadRouteStateSource).toContain('useWorkloadUrlSync');
|
||||
expect(workloadsWorkloadRouteStateSource).toContain('useWorkloadFilterOptions');
|
||||
|
||||
+39
@@ -1,7 +1,12 @@
|
||||
import { createRoot } from 'solid-js';
|
||||
import { renderHook } from '@solidjs/testing-library';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { useWorkloadGuestMetadataState } from '../useWorkloadGuestMetadataState';
|
||||
import {
|
||||
RESOURCE_METADATA_CHANGED_EVENT,
|
||||
type ResourceMetadataChangedDetail,
|
||||
} from '@/utils/resourceMetadataEvents';
|
||||
|
||||
vi.mock('@/api/guestMetadata', () => ({
|
||||
GuestMetadataAPI: {
|
||||
@@ -50,4 +55,38 @@ describe('useWorkloadGuestMetadataState', () => {
|
||||
dispose();
|
||||
});
|
||||
});
|
||||
|
||||
it('applies resource-metadata-changed events under the dispatched metadata id', () => {
|
||||
const { result, cleanup } = renderHook(() => useWorkloadGuestMetadataState());
|
||||
|
||||
window.dispatchEvent(
|
||||
new CustomEvent<ResourceMetadataChangedDetail>(RESOURCE_METADATA_CHANGED_EVENT, {
|
||||
detail: {
|
||||
metadataKind: 'guest',
|
||||
metadataId: 'pve1:node1:104',
|
||||
customUrl: 'https://svc.example.lan',
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
expect(result.guestMetadata()['pve1:node1:104']?.customUrl).toBe('https://svc.example.lan');
|
||||
cleanup();
|
||||
});
|
||||
|
||||
it('ignores agent metadata events', () => {
|
||||
const { result, cleanup } = renderHook(() => useWorkloadGuestMetadataState());
|
||||
|
||||
window.dispatchEvent(
|
||||
new CustomEvent<ResourceMetadataChangedDetail>(RESOURCE_METADATA_CHANGED_EVENT, {
|
||||
detail: {
|
||||
metadataKind: 'agent',
|
||||
metadataId: 'machine-1',
|
||||
customUrl: 'https://machine.example.lan',
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
expect(result.guestMetadata()['machine-1']).toBeUndefined();
|
||||
cleanup();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,6 +5,10 @@ import { getOrgID } from '@/utils/apiClient';
|
||||
import { logger } from '@/utils/logger';
|
||||
import { STORAGE_KEYS } from '@/utils/localStorage';
|
||||
import { normalizeOrgScope } from '@/utils/orgScope';
|
||||
import {
|
||||
RESOURCE_METADATA_CHANGED_EVENT,
|
||||
type ResourceMetadataChangedDetail,
|
||||
} from '@/utils/resourceMetadataEvents';
|
||||
import { eventBus } from '@/stores/events';
|
||||
|
||||
type GuestMetadataRecord = Record<string, GuestMetadata>;
|
||||
@@ -296,43 +300,29 @@ export function useWorkloadGuestMetadataState() {
|
||||
void refreshGuestMetadata();
|
||||
|
||||
const handleMetadataChanged = (event: Event) => {
|
||||
const customEvent = event as CustomEvent;
|
||||
logger.debug('[Workloads] Metadata changed event received', customEvent.detail);
|
||||
const detail = (event as CustomEvent<ResourceMetadataChangedDetail>).detail;
|
||||
logger.debug('[Workloads] Metadata changed event received', detail);
|
||||
|
||||
if (customEvent.detail?.payload) {
|
||||
let { guestId, url } = customEvent.detail.payload;
|
||||
if (guestId) {
|
||||
if (guestId.includes(':')) {
|
||||
const parts = guestId.split(':');
|
||||
if (parts.length === 3) {
|
||||
const [instance, _node, vmid] = parts;
|
||||
guestId = `${instance}-${vmid}`;
|
||||
logger.debug('[Workloads] Normalized optimistic guestId', {
|
||||
original: customEvent.detail.payload.guestId,
|
||||
normalized: guestId,
|
||||
});
|
||||
}
|
||||
}
|
||||
// Agent (host machine) metadata never keys workload rows; only guest and
|
||||
// docker app-container URLs surface in the workloads table.
|
||||
if (detail?.metadataKind === 'agent') return;
|
||||
|
||||
logger.debug('[Workloads] Applying optimistic metadata update', { guestId, url });
|
||||
handleCustomUrlUpdate(guestId, url || '');
|
||||
return;
|
||||
}
|
||||
if (detail?.metadataId) {
|
||||
handleCustomUrlUpdate(detail.metadataId, detail.customUrl ?? '');
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug('Metadata changed event received, refreshing...');
|
||||
void refreshGuestMetadata();
|
||||
};
|
||||
|
||||
logger.debug('[Workloads] Adding pulse:metadata-changed listener');
|
||||
window.addEventListener('pulse:metadata-changed', handleMetadataChanged);
|
||||
window.addEventListener(RESOURCE_METADATA_CHANGED_EVENT, handleMetadataChanged);
|
||||
const unsubscribeOrgSwitched = eventBus.on('org_switched', (nextOrgID) => {
|
||||
setOrgScope(normalizeOrgScope(nextOrgID));
|
||||
void refreshGuestMetadata();
|
||||
});
|
||||
|
||||
onCleanup(() => {
|
||||
window.removeEventListener('pulse:metadata-changed', handleMetadataChanged);
|
||||
window.removeEventListener(RESOURCE_METADATA_CHANGED_EVENT, handleMetadataChanged);
|
||||
unsubscribeOrgSwitched();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user