feat: per-server notification thresholds with alert on agent metrics push
This commit is contained in:
@@ -270,6 +270,12 @@ $canManage = $server_role === 'owner' || $server_role === 'manager';
|
||||
<i class="fas fa-sync-alt"></i>
|
||||
<span>Restart Service</span>
|
||||
</button>
|
||||
<?php if ($server_role === 'owner'): ?>
|
||||
<button class="action-card" onclick="showThresholdModal()">
|
||||
<i class="fas fa-bell"></i>
|
||||
<span>Notification Thresholds</span>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -297,6 +303,55 @@ $canManage = $server_role === 'owner' || $server_role === 'manager';
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="thresholdModal" class="modal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-header">
|
||||
<h3><i class="fas fa-bell"></i> Notification Thresholds</h3>
|
||||
<button type="button" class="modal-close" onclick="closeThresholdModal()">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="text-muted" style="margin-bottom:20px">
|
||||
Notifications are sent to all users with access to this server when the agent reports values
|
||||
exceeding these thresholds. Only the server owner can modify them.
|
||||
</p>
|
||||
<form id="thresholdForm" onsubmit="return false">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Resource</th>
|
||||
<th>Warning (%)</th>
|
||||
<th>Critical (%)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach (['cpu' => 'CPU', 'ram' => 'RAM', 'disk' => 'Disk'] as $key => $label): ?>
|
||||
<tr>
|
||||
<td><strong><?= $label ?></strong></td>
|
||||
<td>
|
||||
<input type="number" name="<?= $key ?>_warning"
|
||||
value="<?= htmlspecialchars((string)($server["threshold_{$key}_warning"] ?? 80)) ?>"
|
||||
min="0" max="100" step="0.01" class="form-control" style="width:120px">
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" name="<?= $key ?>_critical"
|
||||
value="<?= htmlspecialchars((string)($server["threshold_{$key}_critical"] ?? 95)) ?>"
|
||||
min="0" max="100" step="0.01" class="form-control" style="width:120px">
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary" onclick="saveThresholds()"><i class="fas fa-save"></i> Save</button>
|
||||
<button class="btn btn-secondary" onclick="closeThresholdModal()">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form id="csrfForm" style="display:none">
|
||||
<input type="hidden" name="_csrf_token" value="<?= $this->csrfToken() ?>">
|
||||
</form>
|
||||
@@ -591,4 +646,41 @@ function refreshMetrics() {
|
||||
}
|
||||
|
||||
setInterval(refreshMetrics, 30000);
|
||||
|
||||
function showThresholdModal() {
|
||||
document.getElementById('thresholdModal').style.display = 'flex';
|
||||
document.getElementById('thresholdModal').onclick = function(e) {
|
||||
if (e.target === this) closeThresholdModal();
|
||||
};
|
||||
}
|
||||
|
||||
function closeThresholdModal() {
|
||||
document.getElementById('thresholdModal').style.display = 'none';
|
||||
}
|
||||
|
||||
function saveThresholds() {
|
||||
const form = document.getElementById('thresholdForm');
|
||||
const data = new URLSearchParams(new FormData(form));
|
||||
data.append('_csrf_token', getCsrfToken());
|
||||
|
||||
document.querySelector('#thresholdModal .btn-primary').disabled = true;
|
||||
|
||||
fetch('/servers/<?= $server['id'] ?>/thresholds', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'X-CSRF-Token': getCsrfToken(),
|
||||
},
|
||||
body: data.toString(),
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(d => {
|
||||
showToast(d.success ? 'success' : 'error', d.message ?? d.error);
|
||||
if (d.success) closeThresholdModal();
|
||||
})
|
||||
.catch(e => showToast('error', 'Request failed: ' + e.message))
|
||||
.finally(() => {
|
||||
document.querySelector('#thresholdModal .btn-primary').disabled = false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user