mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-14 08:36:07 +00:00
891d3a8759
* feat(memory): add memory threshold alerts
Add memory (RAM) threshold alerts following the same architecture as
CPU alerts: CheckMemJob with @every 1m cadence, memoryAlarmWanted gate,
tgMemory/smtpMemory per-subscriber settings (default 80%), EventBusCheckboxes
with inline threshold input, i18n for en-US/ru-RU with English defaults.
# Conflicts:
# internal/web/translation/ar-EG.json
# internal/web/translation/es-ES.json
# internal/web/translation/fa-IR.json
# internal/web/translation/id-ID.json
# internal/web/translation/ja-JP.json
# internal/web/translation/pt-BR.json
# internal/web/translation/ru-RU.json
# internal/web/translation/tr-TR.json
# internal/web/translation/uk-UA.json
# internal/web/translation/vi-VN.json
# internal/web/translation/zh-CN.json
# internal/web/translation/zh-TW.json
* fix: address code review findings for memory alerts
- Remove dead settingService field from CheckMemJob
- Fix cpuThreshold double-emoji in 12 locale files (code prepends 🔴)
- Align TgCpu/TgMemory fields in entity.go
- Add missing SetTgMemory function
* fix: restore settingService in CheckMemJob for consistency with CheckCpuJob
103 lines
3.0 KiB
TypeScript
103 lines
3.0 KiB
TypeScript
import { InputNumber } from 'antd';
|
|
import { CloudServerOutlined, ThunderboltOutlined, DesktopOutlined, DashboardOutlined, SafetyOutlined } from '@ant-design/icons';
|
|
import type { AllSetting } from '@/models/setting';
|
|
import { NotificationLayout } from './NotificationLayout';
|
|
import { NotificationGroup } from './NotificationGroup';
|
|
import type { NotificationGroupConfig } from './types';
|
|
|
|
const GROUPS: NotificationGroupConfig[] = [
|
|
{
|
|
icon: <CloudServerOutlined />,
|
|
title: 'eventGroupOutbound',
|
|
events: [
|
|
{ key: 'outbound.down', label: 'eventOutboundDown', settingKey: '' },
|
|
{ key: 'outbound.up', label: 'eventOutboundUp', settingKey: '' },
|
|
],
|
|
},
|
|
{
|
|
icon: <ThunderboltOutlined />,
|
|
title: 'eventGroupXray',
|
|
events: [
|
|
{ key: 'xray.crash', label: 'eventXrayCrash', settingKey: '' },
|
|
],
|
|
},
|
|
{
|
|
icon: <DesktopOutlined />,
|
|
title: 'eventGroupNode',
|
|
events: [
|
|
{ key: 'node.down', label: 'eventNodeDown', settingKey: '' },
|
|
{ key: 'node.up', label: 'eventNodeUp', settingKey: '' },
|
|
],
|
|
},
|
|
{
|
|
icon: <DashboardOutlined />,
|
|
title: 'eventGroupSystem',
|
|
events: [
|
|
{
|
|
key: 'cpu.high',
|
|
label: 'eventCPUHigh',
|
|
settingKey: 'smtpCpu',
|
|
extra: ({ value, onChange }) => (
|
|
<InputNumber size="small" min={0} max={100} value={value} onChange={onChange} style={{ width: 80 }} />
|
|
),
|
|
},
|
|
{
|
|
key: 'memory.high',
|
|
label: 'eventMemoryHigh',
|
|
settingKey: 'smtpMemory',
|
|
extra: ({ value, onChange }) => (
|
|
<InputNumber size="small" min={0} max={100} value={value} onChange={onChange} style={{ width: 80 }} />
|
|
),
|
|
},
|
|
],
|
|
},
|
|
{
|
|
icon: <SafetyOutlined />,
|
|
title: 'eventGroupSecurity',
|
|
events: [
|
|
{ key: 'login.attempt', label: 'eventLoginAttempt', settingKey: '' },
|
|
],
|
|
},
|
|
];
|
|
|
|
interface Props {
|
|
allSetting: AllSetting;
|
|
updateSetting: (patch: Partial<AllSetting>) => void;
|
|
}
|
|
|
|
export function EmailNotifications({ allSetting, updateSetting }: Props) {
|
|
const events = allSetting.smtpEnabledEvents || '';
|
|
const selected = events ? events.split(',').map((s) => s.trim()).filter(Boolean) : [];
|
|
|
|
function toggle(key: string) {
|
|
const next = selected.includes(key)
|
|
? selected.filter((e) => e !== key)
|
|
: [...selected, key];
|
|
updateSetting({ smtpEnabledEvents: next.join(',') });
|
|
}
|
|
|
|
function toggleAll(keys: string[]) {
|
|
const allSelected = keys.every((v) => selected.includes(v));
|
|
const next = allSelected
|
|
? selected.filter((v) => !keys.includes(v))
|
|
: [...new Set([...selected, ...keys])];
|
|
updateSetting({ smtpEnabledEvents: next.join(',') });
|
|
}
|
|
|
|
return (
|
|
<NotificationLayout>
|
|
{GROUPS.map((group, i) => (
|
|
<NotificationGroup
|
|
key={i}
|
|
config={group}
|
|
selected={selected}
|
|
onToggle={toggle}
|
|
onToggleAll={toggleAll}
|
|
allSetting={allSetting}
|
|
updateSetting={updateSetting}
|
|
/>
|
|
))}
|
|
</NotificationLayout>
|
|
);
|
|
}
|