mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-30 12:09:15 +00:00
feat: add ON/OFF toggle for host threshold alerts (#1456)
* feat: add ON/OFF toggle for host threshold alerts Add host_alerts_enabled setting (default ON) as a master switch for CPU, RAM, and disk host threshold evaluation. When OFF, the four threshold controls in Settings > Host Alerts are disabled and MonitorService skips the systeminformation calls and alert dispatch entirely, while clearing stale suppression state so re-enabling starts fresh. The dashboard Configuration Status card shows "Off" when host threshold alerts are disabled. Crash capture, health gate, deploy guardrails, stack alert rules, and the Docker janitor are all unaffected. * fix: exit NumberChip edit mode when externally disabled When the host threshold alerts master toggle is turned OFF while a NumberChip is in edit mode, force-exit edit mode so the chip renders the greyed-out button state consistently with the other chips.
This commit is contained in:
@@ -208,7 +208,9 @@ export function ConfigurationStatus({ onOpenSection }: ConfigurationStatusProps
|
||||
)}
|
||||
<Row
|
||||
label="Alert thresholds"
|
||||
value={`CPU ${thresholds.cpuLimit}% · RAM ${thresholds.ramLimit}% · Disk ${thresholds.diskLimit}%`}
|
||||
value={thresholds.hostAlertsEnabled === false
|
||||
? 'Off'
|
||||
: `CPU ${thresholds.cpuLimit}% · RAM ${thresholds.ramLimit}% · Disk ${thresholds.diskLimit}%`}
|
||||
onClick={open('host-alerts')}
|
||||
/>
|
||||
<Row
|
||||
|
||||
@@ -33,7 +33,7 @@ function makePayload(overrides: Partial<ConfigurationStatusPayload> = {}): Confi
|
||||
ssoProvider: null,
|
||||
scanPolicies: { total: 0, enabled: 0, locked: true },
|
||||
},
|
||||
thresholds: { cpuLimit: 90, ramLimit: 90, diskLimit: 90, dockerJanitorGb: 5, globalCrash: false },
|
||||
thresholds: { cpuLimit: 90, ramLimit: 90, diskLimit: 90, dockerJanitorGb: 5, globalCrash: false, hostAlertsEnabled: true },
|
||||
backup: { provider: 'disabled', autoUpload: false, locked: false },
|
||||
...overrides,
|
||||
};
|
||||
@@ -118,3 +118,32 @@ describe('ConfigurationStatus row visibility', () => {
|
||||
expect(screen.getByText('Google')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('ConfigurationStatus threshold display', () => {
|
||||
it('renders threshold values when hostAlertsEnabled is true', () => {
|
||||
useConfigurationStatusMock.mockReturnValue({
|
||||
status: makePayload({ thresholds: { cpuLimit: 80, ramLimit: 85, diskLimit: 90, dockerJanitorGb: 5, globalCrash: true, hostAlertsEnabled: true } }),
|
||||
loading: false,
|
||||
});
|
||||
render(<ConfigurationStatus />);
|
||||
expect(screen.getByText('CPU 80% · RAM 85% · Disk 90%')).toBeDefined();
|
||||
});
|
||||
|
||||
it('renders OFF badge when hostAlertsEnabled is false', () => {
|
||||
useConfigurationStatusMock.mockReturnValue({
|
||||
status: makePayload({
|
||||
thresholds: { cpuLimit: 80, ramLimit: 85, diskLimit: 90, dockerJanitorGb: 5, globalCrash: true, hostAlertsEnabled: false },
|
||||
}),
|
||||
loading: false,
|
||||
});
|
||||
render(<ConfigurationStatus />);
|
||||
// StatusBadge uppercases 'Off' to 'OFF'. Since backup.provider is
|
||||
// 'disabled' (also rendered as OFF), there are two OFF badges.
|
||||
// Verify the Alert thresholds row specifically shows OFF.
|
||||
const thresholdRow = screen.getByText('Alert thresholds').closest('button');
|
||||
expect(thresholdRow).toBeDefined();
|
||||
// The OFF badge is the span inside the row that has font-mono + uppercase.
|
||||
const badge = thresholdRow!.querySelector('.font-mono');
|
||||
expect(badge?.textContent?.trim()).toBe('OFF');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,7 +51,7 @@ beforeEach(() => {
|
||||
ssoProvider: null,
|
||||
scanPolicies: { total: 0, enabled: 0, locked: true },
|
||||
},
|
||||
thresholds: { cpuLimit: 90, ramLimit: 90, diskLimit: 90, dockerJanitorGb: 5, globalCrash: false },
|
||||
thresholds: { cpuLimit: 90, ramLimit: 90, diskLimit: 90, dockerJanitorGb: 5, globalCrash: false, hostAlertsEnabled: true },
|
||||
backup: { provider: 'disabled', autoUpload: false, locked: false },
|
||||
})));
|
||||
useNodesMock.mockReset();
|
||||
|
||||
@@ -37,6 +37,7 @@ export interface ConfigurationStatus {
|
||||
diskLimit: number;
|
||||
dockerJanitorGb: number;
|
||||
globalCrash: boolean;
|
||||
hostAlertsEnabled: boolean;
|
||||
};
|
||||
backup: {
|
||||
provider: 'disabled' | 'sencho' | 'custom';
|
||||
|
||||
Reference in New Issue
Block a user