mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-23 16:58:31 +02:00
fixes, meaningful error messages and new features
This commit is contained in:
6
templates/panel/bootstrap.min.css
vendored
Normal file
6
templates/panel/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
79
templates/panel/index.html
Executable file
79
templates/panel/index.html
Executable file
@@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link href="bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="style.css" rel="stylesheet" />
|
||||
<title>Route Panel</title>
|
||||
</head>
|
||||
|
||||
<body class="m-3">
|
||||
<script src="index.js" defer></script>
|
||||
<div class="container">
|
||||
<h1 class="text-success">Route Panel</h1>
|
||||
<div class="row">
|
||||
<div class="table-responsive col-md-auto flex-shrink-1">
|
||||
<table class="table table-striped table-dark caption-top">
|
||||
<caption>
|
||||
HTTP Proxies
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Alias</th>
|
||||
<th>Path</th>
|
||||
<th>Path Mode</th>
|
||||
<th>URL</th>
|
||||
<th>Health</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range $alias, $pathPoolMap := .HTTPRoutes.Iterator}} {{range
|
||||
$path, $lbPool := $pathPoolMap.Iterator}} {{range $_, $route :=
|
||||
$lbPool.Iterator}}
|
||||
<tr>
|
||||
<td>{{$alias}}</td>
|
||||
<td>{{$path}}</td>
|
||||
<td>{{$route.PathMode}}</td>
|
||||
<td id="url-cell">{{$route.Url.String}}</td>
|
||||
<td class="align-middle" id="health-cell">
|
||||
<div class="health-circle"></div>
|
||||
</td>
|
||||
<!-- Health column -->
|
||||
</tr>
|
||||
{{end}} {{end}} {{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="table-responsive col-md">
|
||||
<table class="table table-striped table-dark caption-top w-auto">
|
||||
<caption>
|
||||
Streams
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Alias</th>
|
||||
<th>Source</th>
|
||||
<th>Target</th>
|
||||
<th>Health</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range $_, $route := .StreamRoutes.Iterator}}
|
||||
<tr>
|
||||
<td>{{$route.Alias}}</td>
|
||||
<td>{{$route.ListeningUrl}}</td>
|
||||
<td id="url-cell">{{$route.TargetUrl}}</td>
|
||||
<td class="align-middle" id="health-cell">
|
||||
<div class="health-circle"></div>
|
||||
</td>
|
||||
<!-- Health column -->
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
34
templates/panel/index.js
Normal file
34
templates/panel/index.js
Normal file
@@ -0,0 +1,34 @@
|
||||
function checkHealth(url, cell) {
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function () {
|
||||
if (this.readyState != 4) {
|
||||
return;
|
||||
}
|
||||
if (this.status === 200) {
|
||||
cell.innerHTML = '<div class="health-circle"></div>'; // Green circle for healthy
|
||||
} else {
|
||||
cell.innerHTML =
|
||||
'<div class="health-circle" style="background-color: #dc3545;"></div>'; // Red circle for unhealthy
|
||||
}
|
||||
};
|
||||
url =
|
||||
window.location.origin + "/checkhealth?target=" + encodeURIComponent(url);
|
||||
xhttp.open("HEAD", url, true);
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
function updateHealthStatus() {
|
||||
let rows = document.querySelectorAll("tbody tr");
|
||||
rows.forEach((row) => {
|
||||
let url = row.querySelector("#url-cell").textContent;
|
||||
let cell = row.querySelector("#health-cell"); // Health column cell
|
||||
checkHealth(url, cell);
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
updateHealthStatus();
|
||||
|
||||
// Update health status every 5 seconds
|
||||
setInterval(updateHealthStatus, 5000);
|
||||
});
|
||||
43
templates/panel/style.css
Normal file
43
templates/panel/style.css
Normal file
@@ -0,0 +1,43 @@
|
||||
body {
|
||||
background-color: #131516;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
tr {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
table th:first-child {
|
||||
border-radius: 10px 0 0 10px;
|
||||
}
|
||||
|
||||
table th:last-child {
|
||||
border-radius: 0 10px 10px 0;
|
||||
}
|
||||
|
||||
table td:first-of-type {
|
||||
border-top-left-radius: 10px;
|
||||
border-bottom-left-radius: 10px;
|
||||
}
|
||||
|
||||
table td:last-of-type {
|
||||
border-top-right-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
}
|
||||
|
||||
table caption {
|
||||
color: antiquewhite;
|
||||
}
|
||||
|
||||
.health-circle {
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
background-color: #28a745;
|
||||
border-radius: 50%;
|
||||
margin: auto;
|
||||
}
|
||||
Reference in New Issue
Block a user