adding editing
Deploy / deploy (push) Successful in 8s

This commit is contained in:
2026-05-06 18:23:36 +02:00
parent 3d3895e47b
commit 08df9bfe5c
3 changed files with 74 additions and 12 deletions
+50 -12
View File
@@ -249,7 +249,7 @@ pre.raw-line { background: var(--bs-tertiary-bg); padding: .75rem; border-radius
<div class="page-section" id="page-rules">
<div class="d-flex justify-content-between align-items-center mb-3">
<h5 class="mb-0"><i class="bi bi-sliders me-2"></i>Alert Rules</h5>
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#ruleModal"><i class="bi bi-plus-lg"></i> Add Rule</button>
<button class="btn btn-primary btn-sm" onclick="resetRuleForm();new bootstrap.Modal(document.getElementById('ruleModal')).show()"><i class="bi bi-plus-lg"></i> Add Rule</button>
</div>
<div class="card">
<div class="card-body p-0">
@@ -386,19 +386,20 @@ pre.raw-line { background: var(--bs-tertiary-bg); padding: .75rem; border-radius
<div class="modal-dialog">
<div class="modal-content">
<form id="ruleForm">
<div class="modal-header"><h5 class="modal-title">Add Alert Rule</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
<div class="modal-header"><h5 class="modal-title" id="ruleModalTitle">Add Alert Rule</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
<div class="modal-body">
<input type="hidden" name="id" id="ruleFormId" value="">
<div class="mb-3">
<label class="form-label">Name</label>
<input type="text" class="form-control" name="name" required placeholder="e.g. PHP Error">
<input type="text" class="form-control" name="name" id="ruleFormName" required placeholder="e.g. SSH Login">
</div>
<div class="mb-3">
<label class="form-label">Pattern <small class="text-secondary">(PHP regex)</small></label>
<input type="text" class="form-control" name="pattern" required placeholder="/error/i">
<input type="text" class="form-control" name="pattern" id="ruleFormPattern" required placeholder="/sshd.*Accepted/i">
</div>
<div class="mb-3">
<label class="form-label">Severity</label>
<select class="form-select" name="severity" required>
<select class="form-select" name="severity" id="ruleFormSeverity" required>
<option value="emergency">Emergency</option>
<option value="critical_high">Critical High</option>
<option value="critical">Critical</option>
@@ -414,11 +415,15 @@ pre.raw-line { background: var(--bs-tertiary-bg); padding: .75rem; border-radius
</div>
<div class="mb-3">
<label class="form-label">Rate Limit <small class="text-secondary">(seconds, empty = no limit)</small></label>
<input type="number" class="form-control" name="rate_limit_seconds" placeholder="60">
<input type="number" class="form-control" name="rate_limit_seconds" id="ruleFormRateLimit" placeholder="60">
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" name="active" id="ruleFormActive" checked>
<label class="form-check-label" for="ruleFormActive">Active</label>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Add Rule</button>
<button type="submit" class="btn btn-primary" id="ruleFormSubmit">Add Rule</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
</div>
</form>
@@ -790,7 +795,7 @@ async function loadRules() {
<td>${severityBadge(r.severity)}</td>
<td>${r.rate_limit_seconds ? r.rate_limit_seconds + 's' : '—'}</td>
<td>${r.active ? '<span class="badge bg-success">Active</span>' : '<span class="badge bg-secondary">Inactive</span>'}</td>
<td><button class="btn btn-outline-danger btn-sm py-0" onclick="deleteRule(${r.id})"><i class="bi bi-trash"></i></button></td>
<td><button class="btn btn-outline-primary btn-sm py-0 me-1" onclick="editRule(${r.id})"><i class="bi bi-pencil"></i></button><button class="btn btn-outline-danger btn-sm py-0" onclick="deleteRule(${r.id})"><i class="bi bi-trash"></i></button></td>
</tr>`).join('');
}
} catch (e) { console.error('rules error', e); }
@@ -805,18 +810,51 @@ async function deleteRule(id) {
} catch (e) { toast('Delete failed', 'danger'); }
}
function editRule(id) {
const r = state.rules.find(x => x.id === id);
if (!r) return;
document.getElementById('ruleModalTitle').textContent = 'Edit Rule';
document.getElementById('ruleFormSubmit').textContent = 'Update Rule';
document.getElementById('ruleFormId').value = r.id;
document.getElementById('ruleFormName').value = r.name;
document.getElementById('ruleFormPattern').value = r.pattern;
document.getElementById('ruleFormSeverity').value = r.severity;
document.getElementById('ruleFormRateLimit').value = r.rate_limit_seconds || '';
document.getElementById('ruleFormActive').checked = r.active;
new bootstrap.Modal(document.getElementById('ruleModal')).show();
}
function resetRuleForm() {
document.getElementById('ruleModalTitle').textContent = 'Add Alert Rule';
document.getElementById('ruleFormSubmit').textContent = 'Add Rule';
document.getElementById('ruleFormId').value = '';
document.getElementById('ruleForm').reset();
document.getElementById('ruleFormActive').checked = true;
}
document.getElementById('ruleModal').addEventListener('hidden.bs.modal', resetRuleForm);
document.getElementById('ruleForm').addEventListener('submit', async e => {
e.preventDefault();
const data = Object.fromEntries(new FormData(e.target));
if (data.rate_limit_seconds) data.rate_limit_seconds = parseInt(data.rate_limit_seconds);
else data.rate_limit_seconds = null;
data.active = !!data.active;
const id = data.id;
delete data.id;
try {
await api('/rules', { method: 'POST', body: JSON.stringify(data) });
toast('Rule added');
if (id) {
await api('/rules/' + id, { method: 'PUT', body: JSON.stringify(data) });
toast('Rule updated');
} else {
await api('/rules', { method: 'POST', body: JSON.stringify(data) });
toast('Rule added');
}
bootstrap.Modal.getInstance(document.getElementById('ruleModal')).hide();
e.target.reset();
loadRules();
} catch (err) { toast('Failed to add rule', 'danger'); }
} catch (err) { toast('Failed to save rule', 'danger'); }
});
// --- SETTINGS ---