This commit is contained in:
@@ -92,19 +92,104 @@
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.usage-bar {
|
||||
position: relative;
|
||||
background-color: #333;
|
||||
border-radius: 8px;
|
||||
height: 20px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.usage-fill {
|
||||
height: 100%;
|
||||
width: 0%;
|
||||
background-color: #00e676; /* initial */
|
||||
transition: width 0.5s ease, background-color 0.4s ease;
|
||||
border-radius: 8px 0 0 8px;
|
||||
}
|
||||
|
||||
.usage-text {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
user-select: none;
|
||||
text-shadow: 0 0 5px rgba(0,0,0,0.7);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="system-stats" class="card" style="margin-bottom: 1.5rem;">
|
||||
<div>
|
||||
<label>CPU Usage</label>
|
||||
<div class="usage-bar">
|
||||
<div id="cpu-bar" class="usage-fill"></div>
|
||||
<span id="cpu-percent" class="usage-text">0%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 1rem;">
|
||||
<label>Memory Usage</label>
|
||||
<div class="usage-bar">
|
||||
<div id="mem-bar" class="usage-fill"></div>
|
||||
<span id="mem-percent" class="usage-text">0%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="page-title">🧠 Task Manager</h1>
|
||||
<div
|
||||
id="htop-wrapper"
|
||||
hx-get="/taskmanager/htop?sort={{.CurrentSort}}&order={{.CurrentOrder}}"
|
||||
hx-trigger="load, every 1s"
|
||||
hx-target="#process-table"
|
||||
hx-swap="innerHTML">
|
||||
|
||||
<div id="process-table" class="card">
|
||||
{{template "table.html" .}}
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
function updateUsage() {
|
||||
fetch("/taskmanager/usage")
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
const cpu = Math.round(data.cpu);
|
||||
const mem = Math.round(data.mem);
|
||||
|
||||
updateBar('cpu-bar', 'cpu-percent', cpu);
|
||||
updateBar('mem-bar', 'mem-percent', mem);
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
|
||||
function updateBar(barId, textId, percent) {
|
||||
const bar = document.getElementById(barId);
|
||||
const text = document.getElementById(textId);
|
||||
|
||||
bar.style.width = percent + '%';
|
||||
text.textContent = percent + '%';
|
||||
|
||||
// Set interpolated color from green to red
|
||||
bar.style.backgroundColor = getInterpolatedColor(percent);
|
||||
}
|
||||
|
||||
function getInterpolatedColor(percent) {
|
||||
// Clamp between 0–100
|
||||
percent = Math.max(0, Math.min(100, percent));
|
||||
|
||||
let r, g;
|
||||
|
||||
if (percent <= 50) {
|
||||
// green (0%) to yellow (50%)
|
||||
r = Math.floor(255 * (percent / 50)); // 0 → 255
|
||||
g = 230; // stay green
|
||||
} else {
|
||||
// yellow (50%) to red (100%)
|
||||
r = 255;
|
||||
g = Math.floor(230 - 230 * ((percent - 50) / 50)); // 230 → 0
|
||||
}
|
||||
|
||||
return `rgb(${r},${g},0)`;
|
||||
}
|
||||
|
||||
setInterval(updateUsage, 5000);
|
||||
updateUsage();
|
||||
</script>
|
||||
</html>
|
@@ -1,39 +1,43 @@
|
||||
<div id="process-table" class="card">
|
||||
<div id="process-table" class="card"
|
||||
hx-get="/taskmanager/htop?sort={{.CurrentSort}}&order={{.CurrentOrder}}"
|
||||
hx-trigger="every 2s"
|
||||
hx-target="#process-table"
|
||||
hx-swap="innerHTML">
|
||||
<table >
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<a hx-get="/taskmanager/htop?sort=pid&order={{if and (eq .CurrentSort "pid") (eq .CurrentOrder "asc")}}desc{{else}}asc{{end}}"
|
||||
hx-target="#process-table"
|
||||
hx-swap="outerHTML">
|
||||
hx-swap="innerHTML">
|
||||
PID {{if eq .CurrentSort "pid"}}{{if eq .CurrentOrder "asc"}}↑{{else}}↓{{end}}{{end}}
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a hx-get="/taskmanager/htop?sort=user&order={{if and (eq .CurrentSort "user") (eq .CurrentOrder "asc")}}desc{{else}}asc{{end}}"
|
||||
hx-target="#process-table"
|
||||
hx-swap="outerHTML">
|
||||
hx-swap="innerHTML">
|
||||
User {{if eq .CurrentSort "user"}}{{if eq .CurrentOrder "asc"}}↑{{else}}↓{{end}}{{end}}
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a hx-get="/taskmanager/htop?sort=cmd&order={{if and (eq .CurrentSort "cmd") (eq .CurrentOrder "asc")}}desc{{else}}asc{{end}}"
|
||||
hx-target="#process-table"
|
||||
hx-swap="outerHTML">
|
||||
hx-swap="innerHTML">
|
||||
Command {{if eq .CurrentSort "cmd"}}{{if eq .CurrentOrder "asc"}}↑{{else}}↓{{end}}{{end}}
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a hx-get="/taskmanager/htop?sort=cpu&order={{if and (eq .CurrentSort "cpu") (eq .CurrentOrder "asc")}}desc{{else}}asc{{end}}"
|
||||
hx-target="#process-table"
|
||||
hx-swap="outerHTML">
|
||||
hx-swap="innerHTML">
|
||||
CPU %{{if eq .CurrentSort "cpu"}}{{if eq .CurrentOrder "asc"}}↑{{else}}↓{{end}}{{end}}
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a hx-get="/taskmanager/htop?sort=memory&order={{if and (eq .CurrentSort "memory") (eq .CurrentOrder "asc")}}desc{{else}}asc{{end}}"
|
||||
hx-target="#process-table"
|
||||
hx-swap="outerHTML">
|
||||
hx-swap="innerHTML">
|
||||
Memory {{if eq .CurrentSort "memory"}}{{if eq .CurrentOrder "asc"}}↑{{else}}↓{{end}}{{end}}
|
||||
</a>
|
||||
</th>
|
||||
@@ -67,4 +71,4 @@
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
62
templates/index.html
Normal file
62
templates/index.html
Normal file
@@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Process Dashboard</title>
|
||||
<script src="https://unpkg.com/htmx.org@1.9.5"></script>
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
margin: 2rem;
|
||||
}
|
||||
.top-link {
|
||||
display: block;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
ul#process-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
ul#process-list li {
|
||||
background: #f4f4f4;
|
||||
margin: 0.5rem 0;
|
||||
padding: 0.75rem;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="top-link-container">
|
||||
<a href="/taskmanager/htop" class="top-link" target="_blank" rel="noopener noreferrer">
|
||||
📈 Task Manager
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Header -->
|
||||
<h2>Future Processes</h2>
|
||||
|
||||
<!-- Placeholder List for Future Processes -->
|
||||
<ul id="process-list">
|
||||
<li>📌 Process A (placeholder)</li>
|
||||
<li>📌 Process B (placeholder)</li>
|
||||
<li>📌 Process C (placeholder)</li>
|
||||
</ul>
|
||||
|
||||
<!-- Example Button for Future HTMX Action -->
|
||||
<button
|
||||
hx-get="/get-latest-processes"
|
||||
hx-target="#process-list"
|
||||
hx-swap="innerHTML">
|
||||
🔄 Load Latest Processes
|
||||
</button>
|
||||
|
||||
</body>
|
||||
<style>
|
||||
.top-link-container {
|
||||
text-align: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
||||
</html>
|
Reference in New Issue
Block a user