feat: threshold modal with range sliders and card-based layout #75

Merged
rafaga21 merged 2 commits from feat/server-thresholds into master 2026-06-13 16:33:41 -04:00
2 changed files with 81 additions and 32 deletions

View File

@@ -3134,3 +3134,39 @@ textarea.form-input {
background: var(--bg-hover, #e9ecef);
border-color: var(--text-muted, #888);
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 18px;
height: 18px;
border-radius: 50%;
background: var(--text-primary);
border: 2px solid var(--bg-card);
box-shadow: 0 1px 4px rgba(0,0,0,0.4);
cursor: pointer;
transition: transform 0.1s;
}
input[type="range"]::-webkit-slider-thumb:hover {
transform: scale(1.15);
}
input[type="range"]::-moz-range-thumb {
width: 18px;
height: 18px;
border-radius: 50%;
background: var(--text-primary);
border: 2px solid var(--bg-card);
box-shadow: 0 1px 4px rgba(0,0,0,0.4);
cursor: pointer;
}
input[type="range"]:focus {
outline: none;
}
input[type="range"]::-moz-range-track {
height: 6px;
border-radius: 3px;
}

View File

@@ -304,49 +304,62 @@ $canManage = $server_role === 'owner' || $server_role === 'manager';
</div>
<div id="thresholdModal" class="modal">
<div class="modal-dialog">
<div class="modal-dialog" style="max-width:560px">
<div class="modal-header">
<h3><i class="fas fa-bell"></i> Notification Thresholds</h3>
<button type="button" class="modal-close" onclick="closeThresholdModal()">&times;</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 class="text-muted" style="margin-bottom:24px;font-size:0.9em;line-height:1.5">
When the agent reports values above these thresholds, all users with access to this server
receive a notification and push alert. 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>
<?php $resources = [
'cpu' => ['label' => 'CPU', 'icon' => 'fas fa-microchip', 'color' => 'var(--info)'],
'ram' => ['label' => 'RAM', 'icon' => 'fas fa-memory', 'color' => 'var(--purple)'],
'disk' => ['label' => 'Disk', 'icon' => 'fas fa-hdd', 'color' => 'var(--warning)'],
]; ?>
<?php foreach ($resources as $key => $res): ?>
<div style="background:var(--card-bg);border:1px solid var(--border);border-radius:10px;padding:16px 20px;margin-bottom:12px">
<div style="display:flex;align-items:center;gap:10px;margin-bottom:16px">
<i class="<?= $res['icon'] ?>" style="color:<?= $res['color'] ?>;font-size:1.2em;width:20px;text-align:center"></i>
<strong style="font-size:1em"><?= $res['label'] ?></strong>
</div>
<div style="display:flex;gap:24px;align-items:flex-start">
<div style="flex:1">
<label style="display:flex;align-items:center;gap:6px;font-size:0.82em;color:var(--warning);margin-bottom:6px;font-weight:600">
<i class="fas fa-exclamation-triangle" style="font-size:0.85em"></i> Warning
</label>
<div style="display:flex;align-items:center;gap:10px">
<input type="range" name="<?= $key ?>_warning"
value="<?= htmlspecialchars((string)($server["threshold_{$key}_warning"] ?? 80)) ?>"
min="0" max="100" step="0.5"
oninput="document.getElementById('<?= $key ?>_warn_val').textContent = this.value + '%'"
style="flex:1;height:6px;-webkit-appearance:none;appearance:none;border-radius:3px;background:linear-gradient(to right, var(--success), var(--warning) 50%, var(--danger) 80%);outline:none;cursor:pointer">
<span id="<?= $key ?>_warn_val" style="min-width:52px;font-size:0.95em;font-weight:700;color:var(--warning);text-align:right"><?= htmlspecialchars((string)($server["threshold_{$key}_warning"] ?? 80)) ?>%</span>
</div>
</div>
<div style="flex:1">
<label style="display:flex;align-items:center;gap:6px;font-size:0.82em;color:var(--danger);margin-bottom:6px;font-weight:600">
<i class="fas fa-bolt" style="font-size:0.85em"></i> Critical
</label>
<div style="display:flex;align-items:center;gap:10px">
<input type="range" name="<?= $key ?>_critical"
value="<?= htmlspecialchars((string)($server["threshold_{$key}_critical"] ?? 95)) ?>"
min="0" max="100" step="0.5"
oninput="document.getElementById('<?= $key ?>_crit_val').textContent = this.value + '%'"
style="flex:1;height:6px;-webkit-appearance:none;appearance:none;border-radius:3px;background:linear-gradient(to right, var(--success), var(--warning) 50%, var(--danger) 80%);outline:none;cursor:pointer">
<span id="<?= $key ?>_crit_val" style="min-width:52px;font-size:0.95em;font-weight:700;color:var(--danger);text-align:right"><?= htmlspecialchars((string)($server["threshold_{$key}_critical"] ?? 95)) ?>%</span>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</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-primary" onclick="saveThresholds()"><i class="fas fa-save"></i> Save Thresholds</button>
<button class="btn btn-secondary" onclick="closeThresholdModal()">Cancel</button>
</div>
</div>