diff --git a/frontend-modern/src/components/Settings/NodeModalMonitoringSection.tsx b/frontend-modern/src/components/Settings/NodeModalMonitoringSection.tsx index cbf6f4406..e2dde8bbc 100644 --- a/frontend-modern/src/components/Settings/NodeModalMonitoringSection.tsx +++ b/frontend-modern/src/components/Settings/NodeModalMonitoringSection.tsx @@ -59,6 +59,81 @@ export const NodeModalMonitoringSection: Component +
+ +

+ Control which Proxmox VE resources Pulse ingests. Disable individual collectors to + reduce API load or trim dashboard noise. +

+ + + + + + + + +
+
+ +
+ +

+ Control which Proxmox Backup Server surfaces Pulse ingests. Disable collectors you + don't need. +

+ + + + + + + + + + +
+
+
{ username = parts[0]; } + const pveConfig = + node.type === 'pve' + ? (node as NodeConfig & { + monitorVMs?: boolean; + monitorContainers?: boolean; + monitorStorage?: boolean; + monitorBackups?: boolean; + }) + : undefined; + + const pbsConfig = + node.type === 'pbs' + ? (node as NodeConfig & { + monitorDatastores?: boolean; + monitorSyncJobs?: boolean; + monitorVerifyJobs?: boolean; + monitorPruneJobs?: boolean; + monitorGarbageJobs?: boolean; + }) + : undefined; + const pmgConfig = node.type === 'pmg' ? (node as NodeConfig & { @@ -298,6 +319,10 @@ export const useNodeModalState = (props: NodeModalProps) => { tokenValue: '', fingerprint: ('fingerprint' in node ? node.fingerprint : '') || '', verifySSL: node.verifySSL ?? true, + monitorVMs: pveConfig?.monitorVMs ?? true, + monitorContainers: pveConfig?.monitorContainers ?? true, + monitorStorage: pveConfig?.monitorStorage ?? true, + monitorBackups: pveConfig?.monitorBackups ?? true, monitorPhysicalDisks: node.type === 'pve' ? ((node as NodeConfig & { monitorPhysicalDisks?: boolean }).monitorPhysicalDisks ?? true) @@ -307,6 +332,11 @@ export const useNodeModalState = (props: NodeModalProps) => { ? ((node as NodeConfig & { physicalDiskPollingMinutes?: number }) .physicalDiskPollingMinutes ?? 5) : 5, + monitorDatastores: pbsConfig?.monitorDatastores ?? true, + monitorSyncJobs: pbsConfig?.monitorSyncJobs ?? true, + monitorVerifyJobs: pbsConfig?.monitorVerifyJobs ?? true, + monitorPruneJobs: pbsConfig?.monitorPruneJobs ?? true, + monitorGarbageJobs: pbsConfig?.monitorGarbageJobs ?? true, monitorMailStats: pmgConfig?.monitorMailStats ?? true, monitorQueues: pmgConfig?.monitorQueues ?? true, monitorQuarantine: pmgConfig?.monitorQuarantine ?? true, diff --git a/frontend-modern/src/utils/__tests__/nodeModalPresentation.test.ts b/frontend-modern/src/utils/__tests__/nodeModalPresentation.test.ts index 8a4321afa..b08ee4d99 100644 --- a/frontend-modern/src/utils/__tests__/nodeModalPresentation.test.ts +++ b/frontend-modern/src/utils/__tests__/nodeModalPresentation.test.ts @@ -97,6 +97,40 @@ describe('nodeModalPresentation', () => { }); }); + it('propagates per-surface scope toggles through the pve payload', () => { + const form = { + ...getNodeModalDefaultFormData('pve'), + monitorVMs: false, + monitorContainers: true, + monitorStorage: false, + monitorBackups: true, + }; + expect(buildNodeModalMonitoringPayload('pve', form)).toMatchObject({ + monitorVMs: false, + monitorContainers: true, + monitorStorage: false, + monitorBackups: true, + }); + }); + + it('propagates per-surface scope toggles through the pbs payload', () => { + const form = { + ...getNodeModalDefaultFormData('pbs'), + monitorDatastores: true, + monitorSyncJobs: false, + monitorVerifyJobs: true, + monitorPruneJobs: false, + monitorGarbageJobs: false, + }; + expect(buildNodeModalMonitoringPayload('pbs', form)).toMatchObject({ + monitorDatastores: true, + monitorSyncJobs: false, + monitorVerifyJobs: true, + monitorPruneJobs: false, + monitorGarbageJobs: false, + }); + }); + it('returns canonical node test result presentation', () => { expect(getNodeModalTestResultPresentation('success')).toMatchObject({ icon: 'success', diff --git a/frontend-modern/src/utils/nodeModalPresentation.ts b/frontend-modern/src/utils/nodeModalPresentation.ts index 16701f201..fdda0fe29 100644 --- a/frontend-modern/src/utils/nodeModalPresentation.ts +++ b/frontend-modern/src/utils/nodeModalPresentation.ts @@ -18,8 +18,17 @@ export interface NodeModalFormData { tokenValue: string; fingerprint: string; verifySSL: boolean; + monitorVMs: boolean; + monitorContainers: boolean; + monitorStorage: boolean; + monitorBackups: boolean; monitorPhysicalDisks: boolean; physicalDiskPollingMinutes: number; + monitorDatastores: boolean; + monitorSyncJobs: boolean; + monitorVerifyJobs: boolean; + monitorPruneJobs: boolean; + monitorGarbageJobs: boolean; monitorMailStats: boolean; monitorQueues: boolean; monitorQuarantine: boolean; @@ -47,8 +56,17 @@ export function getNodeModalDefaultFormData( tokenValue: '', fingerprint: '', verifySSL: true, + monitorVMs: true, + monitorContainers: true, + monitorStorage: true, + monitorBackups: true, monitorPhysicalDisks: false, physicalDiskPollingMinutes: 5, + monitorDatastores: true, + monitorSyncJobs: true, + monitorVerifyJobs: true, + monitorPruneJobs: true, + monitorGarbageJobs: true, monitorMailStats: true, monitorQueues: true, monitorQuarantine: true, @@ -150,20 +168,20 @@ export function buildNodeModalMonitoringPayload( switch (nodeType) { case 'pve': return { - monitorVMs: true, - monitorContainers: true, - monitorStorage: true, - monitorBackups: true, + monitorVMs: formData.monitorVMs, + monitorContainers: formData.monitorContainers, + monitorStorage: formData.monitorStorage, + monitorBackups: formData.monitorBackups, monitorPhysicalDisks: formData.monitorPhysicalDisks, physicalDiskPollingMinutes: formData.physicalDiskPollingMinutes, }; case 'pbs': return { - monitorDatastores: true, - monitorSyncJobs: true, - monitorVerifyJobs: true, - monitorPruneJobs: true, - monitorGarbageJobs: true, + monitorDatastores: formData.monitorDatastores, + monitorSyncJobs: formData.monitorSyncJobs, + monitorVerifyJobs: formData.monitorVerifyJobs, + monitorPruneJobs: formData.monitorPruneJobs, + monitorGarbageJobs: formData.monitorGarbageJobs, }; case 'pmg': return {