Debug and enhance reset to defaults feature

Add debug logging to track prop changes and hasCustomGlobalDefaults checks in ResourceTable. Fix quick tips documentation to use 0 instead of -1 for disabling alerts. Add factory defaults and reset support for PBS Servers section. Reorder PBS section to appear before Guests section.
This commit is contained in:
rcourtman
2025-10-11 18:31:57 +00:00
parent 6430838361
commit a08c1ca79d
3 changed files with 90 additions and 47 deletions
@@ -1,4 +1,4 @@
import { For, Show, createSignal } from 'solid-js';
import { For, Show, createSignal, createEffect } from 'solid-js';
import { TogglePrimitive } from '@/components/shared/Toggle';
import { StatusBadge } from '@/components/shared/StatusBadge';
import type { Alert } from '@/types/api';
@@ -138,14 +138,38 @@ export function ResourceTable(props: ResourceTableProps) {
const [activeMetricInput, setActiveMetricInput] = createSignal<{ resourceId: string; metric: string } | null>(null);
const [showDelayRow, setShowDelayRow] = createSignal(false);
// Track changes to global defaults and factory defaults for debugging
createEffect(() => {
console.log('[ResourceTable] createEffect triggered - props changed:', {
title: props.title,
globalDefaults: props.globalDefaults,
factoryDefaults: props.factoryDefaults,
onResetDefaults: !!props.onResetDefaults,
});
});
// Check if global defaults have been customized from factory defaults
const hasCustomGlobalDefaults = () => {
if (!props.globalDefaults || !props.factoryDefaults) return false;
return Object.keys(props.factoryDefaults).some(key => {
console.log('[ResourceTable] hasCustomGlobalDefaults check:', {
globalDefaults: props.globalDefaults,
factoryDefaults: props.factoryDefaults,
title: props.title,
});
if (!props.globalDefaults || !props.factoryDefaults) {
console.log('[ResourceTable] Missing props, returning false');
return false;
}
const result = Object.keys(props.factoryDefaults).some(key => {
const current = props.globalDefaults?.[key];
const factory = props.factoryDefaults?.[key];
return current !== undefined && current !== factory;
const differs = current !== undefined && current !== factory;
if (differs) {
console.log(`[ResourceTable] Difference found: ${key} current=${current} factory=${factory}`);
}
return differs;
});
console.log(`[ResourceTable] hasCustomGlobalDefaults result: ${result}`);
return result;
};
const normalizeMetricKey = (column: string): string => {
@@ -1681,7 +1681,7 @@ const dockerContainersGroupedByHost = createMemo<Record<string, Resource[]>>((pr
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<div class="text-sm text-blue-900 dark:text-blue-100">
<span class="font-medium">Quick tips:</span> Set any threshold to <code class="px-1 py-0.5 bg-blue-100 dark:bg-blue-900/50 rounded text-xs font-mono">-1</code> to disable alerts for that metric. Click on disabled thresholds showing <span class="italic">Off</span> to re-enable them. Resources with custom settings show a <span class="inline-flex items-center px-1.5 py-0.5 bg-blue-100 dark:bg-blue-900/50 text-blue-700 dark:text-blue-300 rounded text-xs">Custom</span> badge.
<span class="font-medium">Quick tips:</span> Set any threshold to <code class="px-1 py-0.5 bg-blue-100 dark:bg-blue-900/50 rounded text-xs font-mono">0</code> to disable alerts for that metric. Click on disabled thresholds showing <span class="italic">Off</span> to re-enable them. Resources with custom settings show a <span class="inline-flex items-center px-1.5 py-0.5 bg-blue-100 dark:bg-blue-900/50 text-blue-700 dark:text-blue-300 rounded text-xs">Custom</span> badge.
</div>
</div>
</div>
@@ -1764,6 +1764,50 @@ const dockerContainersGroupedByHost = createMemo<Record<string, Resource[]>>((pr
</div>
</Show>
<Show when={hasSection('pbs')}>
<div ref={registerSection('pbs')} class="scroll-mt-24">
<ResourceTable
title="PBS Servers"
resources={pbsServersWithOverrides()}
columns={['CPU %', 'Memory %']}
activeAlerts={props.activeAlerts}
emptyMessage="No PBS servers match the current filters."
onEdit={startEditing}
onSaveEdit={saveEdit}
onCancelEdit={cancelEdit}
onRemoveOverride={removeOverride}
onToggleDisabled={toggleDisabled}
onToggleNodeConnectivity={toggleNodeConnectivity}
showOfflineAlertsColumn={true}
editingId={editingId}
editingThresholds={editingThresholds}
setEditingThresholds={setEditingThresholds}
formatMetricValue={formatMetricValue}
hasActiveAlert={hasActiveAlert}
globalDefaults={{ cpu: props.nodeDefaults.cpu, memory: props.nodeDefaults.memory }}
setGlobalDefaults={(value) => {
if (typeof value === 'function') {
const newValue = value({ cpu: props.nodeDefaults.cpu, memory: props.nodeDefaults.memory });
props.setNodeDefaults((prev) => ({ ...prev, cpu: newValue.cpu ?? prev.cpu, memory: newValue.memory ?? prev.memory }));
} else {
props.setNodeDefaults((prev) => ({ ...prev, cpu: value.cpu ?? prev.cpu, memory: value.memory ?? prev.memory }));
}
}}
setHasUnsavedChanges={props.setHasUnsavedChanges}
globalDisableFlag={props.disableAllPBS}
onToggleGlobalDisable={() => props.setDisableAllPBS(!props.disableAllPBS())}
globalDisableOfflineFlag={props.disableAllPBSOffline}
onToggleGlobalDisableOffline={() => props.setDisableAllPBSOffline(!props.disableAllPBSOffline())}
showDelayColumn={true}
globalDelaySeconds={props.timeThresholds().pbs}
metricDelaySeconds={props.metricTimeThresholds().pbs ?? {}}
onMetricDelayChange={(metric, value) => updateMetricDelay('pbs', metric, value)}
factoryDefaults={props.factoryNodeDefaults ? { cpu: props.factoryNodeDefaults.cpu, memory: props.factoryNodeDefaults.memory } : undefined}
onResetDefaults={props.resetNodeDefaults}
/>
</div>
</Show>
<Show when={hasSection('guests')}>
<div ref={registerSection('guests')} class="scroll-mt-24">
<ResourceTable
@@ -1857,48 +1901,6 @@ const dockerContainersGroupedByHost = createMemo<Record<string, Resource[]>>((pr
</div>
</Show>
<Show when={hasSection('pbs')}>
<div ref={registerSection('pbs')} class="scroll-mt-24">
<ResourceTable
title="PBS Servers"
resources={pbsServersWithOverrides()}
columns={['CPU %', 'Memory %']}
activeAlerts={props.activeAlerts}
emptyMessage="No PBS servers match the current filters."
onEdit={startEditing}
onSaveEdit={saveEdit}
onCancelEdit={cancelEdit}
onRemoveOverride={removeOverride}
onToggleDisabled={toggleDisabled}
onToggleNodeConnectivity={toggleNodeConnectivity}
showOfflineAlertsColumn={true}
editingId={editingId}
editingThresholds={editingThresholds}
setEditingThresholds={setEditingThresholds}
formatMetricValue={formatMetricValue}
hasActiveAlert={hasActiveAlert}
globalDefaults={{ cpu: props.nodeDefaults.cpu, memory: props.nodeDefaults.memory }}
setGlobalDefaults={(value) => {
if (typeof value === 'function') {
const newValue = value({ cpu: props.nodeDefaults.cpu, memory: props.nodeDefaults.memory });
props.setNodeDefaults((prev) => ({ ...prev, cpu: newValue.cpu ?? prev.cpu, memory: newValue.memory ?? prev.memory }));
} else {
props.setNodeDefaults((prev) => ({ ...prev, cpu: value.cpu ?? prev.cpu, memory: value.memory ?? prev.memory }));
}
}}
setHasUnsavedChanges={props.setHasUnsavedChanges}
globalDisableFlag={props.disableAllPBS}
onToggleGlobalDisable={() => props.setDisableAllPBS(!props.disableAllPBS())}
globalDisableOfflineFlag={props.disableAllPBSOffline}
onToggleGlobalDisableOffline={() => props.setDisableAllPBSOffline(!props.disableAllPBSOffline())}
showDelayColumn={true}
globalDelaySeconds={props.timeThresholds().pbs}
metricDelaySeconds={props.metricTimeThresholds().pbs ?? {}}
onMetricDelayChange={(metric, value) => updateMetricDelay('pbs', metric, value)}
/>
</div>
</Show>
</Show>
<Show when={activeTab() === 'pmg'}>
+17
View File
@@ -1895,6 +1895,15 @@ interface ThresholdsTabProps {
setDisableAllPMGOffline: (value: boolean) => void;
disableAllDockerHostsOffline: () => boolean;
setDisableAllDockerHostsOffline: (value: boolean) => void;
// Reset functions and factory defaults
resetGuestDefaults?: () => void;
resetNodeDefaults?: () => void;
resetDockerDefaults?: () => void;
resetStorageDefault?: () => void;
factoryGuestDefaults?: Record<string, number | undefined>;
factoryNodeDefaults?: Record<string, number | undefined>;
factoryDockerDefaults?: Record<string, number | undefined>;
factoryStorageDefault?: number;
}
function ThresholdsTab(props: ThresholdsTabProps) {
@@ -1955,6 +1964,14 @@ function ThresholdsTab(props: ThresholdsTabProps) {
setDisableAllPMGOffline={props.setDisableAllPMGOffline}
disableAllDockerHostsOffline={props.disableAllDockerHostsOffline}
setDisableAllDockerHostsOffline={props.setDisableAllDockerHostsOffline}
resetGuestDefaults={props.resetGuestDefaults}
resetNodeDefaults={props.resetNodeDefaults}
resetDockerDefaults={props.resetDockerDefaults}
resetStorageDefault={props.resetStorageDefault}
factoryGuestDefaults={props.factoryGuestDefaults}
factoryNodeDefaults={props.factoryNodeDefaults}
factoryDockerDefaults={props.factoryDockerDefaults}
factoryStorageDefault={props.factoryStorageDefault}
/>
);
}