196 lines
10 KiB
Plaintext
196 lines
10 KiB
Plaintext
@page
|
|
@model Status.Pages.Admin.MonitorsModel
|
|
@{
|
|
ViewData["Title"] = "Manage Monitors";
|
|
ViewData["Page"] = "admin-monitors";
|
|
}
|
|
|
|
@if (!string.IsNullOrEmpty(Model.Message))
|
|
{
|
|
<div class="alert alert-success">✓ @Model.Message</div>
|
|
}
|
|
|
|
<div class="section-header">
|
|
<span class="section-title">Monitors</span>
|
|
<button class="btn btn-primary" onclick="openModal('add-monitor-modal')">+ Add Monitor</button>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<table class="data-table">
|
|
<thead><tr>
|
|
<th>Name</th>
|
|
<th>Type</th>
|
|
<th>Host / URL</th>
|
|
<th>Group</th>
|
|
<th>Interval</th>
|
|
<th>Status</th>
|
|
<th>Visibility</th>
|
|
<th>Actions</th>
|
|
</tr></thead>
|
|
<tbody>
|
|
@foreach (var m in Model.Monitors)
|
|
{
|
|
var badgeClass = m.LastStatus switch {
|
|
MonitorStatus.Up => "badge-up",
|
|
MonitorStatus.Down => "badge-down",
|
|
MonitorStatus.Warning or MonitorStatus.Degraded => "badge-warn",
|
|
_ => "badge-unknown"
|
|
};
|
|
<tr>
|
|
<td style="color:var(--text-primary);font-weight:500">@m.Name
|
|
@if (!m.IsActive) { <span class="badge badge-unknown" style="font-size:8px">PAUSED</span> }
|
|
</td>
|
|
<td class="mono" style="font-size:11px">@m.Type</td>
|
|
<td class="mono" style="font-size:11px;color:var(--text-muted)">@(m.Url ?? (m.Host + (m.Port.HasValue ? ":" + m.Port : "")))</td>
|
|
<td style="font-size:12px">@(m.GroupName ?? "—")</td>
|
|
<td class="mono" style="font-size:11px">@m.IntervalSeconds s</td>
|
|
<td><span class="badge @badgeClass">@m.LastStatus</span></td>
|
|
<td>@(m.IsPublic ? "🌐 Public" : "🔒 Private")</td>
|
|
<td>
|
|
<div class="flex gap-2">
|
|
<form method="post" asp-page-handler="CheckNow" style="display:inline">
|
|
<input type="hidden" name="id" value="@m.Id" />
|
|
<button type="submit" class="btn btn-outline btn-sm" title="Check Now">▶</button>
|
|
</form>
|
|
<button class="btn btn-outline btn-sm" onclick="editMonitor(@m.Id,'@m.Name','@m.Description','@m.Type','@m.Host','@(m.Port?.ToString() ?? "")','@m.Url','@m.ProcessName','@m.IntervalSeconds','@m.TimeoutMs','@m.IsActive'.toLowerCase(),'@m.IsPublic'.toLowerCase(),'@m.Tags','@m.GroupName')">Edit</button>
|
|
<form method="post" asp-page-handler="Delete" style="display:inline" onsubmit="return confirm('Delete @m.Name?')">
|
|
<input type="hidden" name="id" value="@m.Id" />
|
|
<button type="submit" class="btn btn-danger btn-sm">Delete</button>
|
|
</form>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
}
|
|
@if (!Model.Monitors.Any())
|
|
{
|
|
<tr><td colspan="8" style="text-align:center;padding:32px;color:var(--text-muted)">No monitors yet. Add one above.</td></tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Add/Edit Monitor Modal -->
|
|
<div class="modal-overlay" id="add-monitor-modal">
|
|
<div class="modal">
|
|
<div class="modal-header">
|
|
<span class="modal-title" id="modal-title">Add Monitor</span>
|
|
<button class="modal-close" onclick="closeModal('add-monitor-modal')">✕</button>
|
|
</div>
|
|
<form method="post" asp-page-handler="Save">
|
|
<div class="modal-body">
|
|
<input type="hidden" name="EditMonitor.Id" id="edit-id" value="0" />
|
|
<div class="two-col">
|
|
<div class="form-group">
|
|
<label class="form-label">Name *</label>
|
|
<input type="text" name="EditMonitor.Name" id="edit-name" class="form-control" required />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Type *</label>
|
|
<select name="EditMonitor.Type" id="edit-type" class="form-control" onchange="updateTypeFields()">
|
|
<option value="TCP">TCP</option>
|
|
<option value="UDP">UDP</option>
|
|
<option value="HTTP">HTTP</option>
|
|
<option value="HTTPS">HTTPS</option>
|
|
<option value="AppLocal">App (Local)</option>
|
|
<option value="AppRemote">App (Remote)</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Description</label>
|
|
<input type="text" name="EditMonitor.Description" id="edit-desc" class="form-control" />
|
|
</div>
|
|
<div class="two-col" id="host-row">
|
|
<div class="form-group">
|
|
<label class="form-label">Host</label>
|
|
<input type="text" name="EditMonitor.Host" id="edit-host" class="form-control" placeholder="hostname or IP" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Port</label>
|
|
<input type="number" name="EditMonitor.Port" id="edit-port" class="form-control" placeholder="e.g. 443" />
|
|
</div>
|
|
</div>
|
|
<div class="form-group" id="url-row" style="display:none">
|
|
<label class="form-label">URL</label>
|
|
<input type="text" name="EditMonitor.Url" id="edit-url" class="form-control" placeholder="https://example.com" />
|
|
</div>
|
|
<div class="form-group" id="process-row" style="display:none">
|
|
<label class="form-label">Process Name</label>
|
|
<input type="text" name="EditMonitor.ProcessName" id="edit-process" class="form-control" placeholder="nginx" />
|
|
</div>
|
|
<div class="two-col">
|
|
<div class="form-group">
|
|
<label class="form-label">Check Interval (seconds)</label>
|
|
<input type="number" name="EditMonitor.IntervalSeconds" id="edit-interval" class="form-control" value="60" min="10" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Timeout (ms)</label>
|
|
<input type="number" name="EditMonitor.TimeoutMs" id="edit-timeout" class="form-control" value="5000" min="500" />
|
|
</div>
|
|
</div>
|
|
<div class="two-col">
|
|
<div class="form-group">
|
|
<label class="form-label">Group Name</label>
|
|
<input type="text" name="EditMonitor.GroupName" id="edit-group" class="form-control" placeholder="Production" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Tags (comma-separated)</label>
|
|
<input type="text" name="EditMonitor.Tags" id="edit-tags" class="form-control" placeholder="web, api" />
|
|
</div>
|
|
</div>
|
|
<div class="flex gap-3 align-center mt-1">
|
|
<label class="flex align-center gap-2" style="cursor:pointer">
|
|
<label class="toggle">
|
|
<input type="checkbox" name="EditMonitor.IsActive" id="edit-active" checked />
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
<span style="font-size:13px">Active</span>
|
|
</label>
|
|
<label class="flex align-center gap-2" style="cursor:pointer">
|
|
<label class="toggle">
|
|
<input type="checkbox" name="EditMonitor.IsPublic" id="edit-public" checked />
|
|
<span class="toggle-slider"></span>
|
|
</label>
|
|
<span style="font-size:13px">Public (visible to unauthenticated users)</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-outline" onclick="closeModal('add-monitor-modal')">Cancel</button>
|
|
<button type="submit" class="btn btn-primary">Save Monitor</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
@section Scripts {
|
|
<script>
|
|
function updateTypeFields() {
|
|
const type = document.getElementById('edit-type').value;
|
|
document.getElementById('host-row').style.display = ['HTTP','HTTPS'].includes(type) ? 'none' : 'grid';
|
|
document.getElementById('url-row').style.display = ['HTTP','HTTPS'].includes(type) ? 'block' : 'none';
|
|
document.getElementById('process-row').style.display = type === 'AppLocal' ? 'block' : 'none';
|
|
}
|
|
|
|
function editMonitor(id,name,desc,type,host,port,url,process,interval,timeout,active,pub,tags,group) {
|
|
document.getElementById('modal-title').textContent = 'Edit Monitor';
|
|
document.getElementById('edit-id').value = id;
|
|
document.getElementById('edit-name').value = name;
|
|
document.getElementById('edit-desc').value = desc;
|
|
document.getElementById('edit-type').value = type;
|
|
document.getElementById('edit-host').value = host;
|
|
document.getElementById('edit-port').value = port;
|
|
document.getElementById('edit-url').value = url;
|
|
document.getElementById('edit-process').value = process;
|
|
document.getElementById('edit-interval').value = interval;
|
|
document.getElementById('edit-timeout').value = timeout;
|
|
document.getElementById('edit-active').checked = active === 'true';
|
|
document.getElementById('edit-public').checked = pub === 'true';
|
|
document.getElementById('edit-tags').value = tags;
|
|
document.getElementById('edit-group').value = group;
|
|
updateTypeFields();
|
|
openModal('add-monitor-modal');
|
|
}
|
|
</script>
|
|
}
|