prvi poskus

This commit is contained in:
2025-05-17 22:45:37 +02:00
parent c0bbea5c83
commit 21f574aa95
5 changed files with 224 additions and 148 deletions

View File

@@ -21,20 +21,19 @@
<div class="stat"><span class="label">CPU Usage:</span> <span class="value" id="cpu">--</span></div>
<div class="stat"><span class="label">RAM Usage:</span> <span class="value" id="ram">--</span></div>
<div class="stat"><span class="label">SSD Usage:</span> <span class="value" id="disk">--</span></div>
<div class="stat"><span class="label">Uptime:</span> <span class="value" id="uptime">--</span></div>
<div class="stat"><span class="label">Up since:</span> <span class="value" id="uptime">--</span></div>
</div>
<div class="container" style="margin-top:24px;">
<h1>Limit overages</h1>
<form id="addMessageForm" style="margin-bottom:16px;">
<input type="text" id="newMessage" placeholder="Type a message..." style="width:70%;padding:8px;" required>
<button type="submit" class="refresh-btn" style="display:inline-block;margin:0;">Add</button>
</form>
<ul id="messages" style="list-style:none;padding:0;"></ul>
</div>
<div class="container" style="margin-top:24px;">
<h1>Resource Limits</h1>
<script>
</script>
<div class="stat">
<span class="label">CPU Limit:</span>
<input type="range" id="cpuLimit" min="1" max="100" value="50" style="flex:1;margin:0 12px;">
@@ -53,19 +52,134 @@
</div>
<script>
async function fetchOverages() {
try {
const res = await fetch('/overages');
const data = await res.json();
const messages = document.getElementById('messages');
// Replace <ul> with a table for better alignment
// If table doesn't exist, create it
let table = document.getElementById('overagesTable');
if (!table) {
table = document.createElement('table');
table.id = 'overagesTable';
table.style.width = '100%';
table.style.borderCollapse = 'collapse';
table.innerHTML = `
<thead>
<tr>
<th style="text-align:left;padding:8px 4px;">ID</th>
<th style="text-align:center;padding:8px 4px;">CPU</th>
<th style="text-align:center;padding:8px 4px;">RAM</th>
<th style="text-align:center;padding:8px 4px;">DISK</th>
<th style="text-align:left;padding:8px 4px;">Timestamp</th>
<th style="text-align:center;padding:8px 4px;">Action</th>
</tr>
</thead>
<tbody></tbody>
`;
messages.innerHTML = '';
messages.appendChild(table);
}
const tbody = table.querySelector('tbody');
tbody.innerHTML = '';
data.forEach(item => {
const tr = document.createElement('tr');
tr.style.borderBottom = '1px solid #eee';
// ID
const idTd = document.createElement('td');
idTd.textContent = `#${item.id}`;
idTd.style.padding = '8px 4px';
// CPU
const cpuTd = document.createElement('td');
cpuTd.style.textAlign = 'center';
cpuTd.style.padding = '8px 4px';
cpuTd.textContent = item.cpu === 1 ? '↑' : '↓';
cpuTd.style.color = item.cpu === 1 ? 'red' : 'green';
// RAM
const ramTd = document.createElement('td');
ramTd.style.textAlign = 'center';
ramTd.style.padding = '8px 4px';
ramTd.textContent = item.ram === 1 ? '↑' : '↓';
ramTd.style.color = item.ram === 1 ? 'red' : 'green';
// DISK
const diskTd = document.createElement('td');
diskTd.style.textAlign = 'center';
diskTd.style.padding = '8px 4px';
diskTd.textContent = item.disk === 1 ? '↑' : '↓';
diskTd.style.color = item.disk === 1 ? 'red' : 'green';
// Timestamp
const tsTd = document.createElement('td');
const date = new Date(item.timestamp);
tsTd.textContent = date.toLocaleString();
tsTd.style.padding = '8px 4px';
// Delete button
const delTd = document.createElement('td');
delTd.style.textAlign = 'center';
delTd.style.padding = '8px 4px';
const delBtn = document.createElement('button');
delBtn.textContent = 'Delete';
delBtn.style.background = '#e74c3c';
delBtn.style.color = '#fff';
delBtn.style.border = 'none';
delBtn.style.borderRadius = '4px';
delBtn.style.padding = '4px 12px';
delBtn.style.cursor = 'pointer';
delBtn.onclick = async () => {
await fetch(`/overages/${item.id}`, { method: 'DELETE' });
fetchOverages();
};
delTd.appendChild(delBtn);
tr.appendChild(idTd);
tr.appendChild(cpuTd);
tr.appendChild(ramTd);
tr.appendChild(diskTd);
tr.appendChild(tsTd);
tr.appendChild(delTd);
tbody.appendChild(tr);
});
// If no data, show a message
if (data.length === 0) {
const tr = document.createElement('tr');
const td = document.createElement('td');
td.colSpan = 6;
td.style.textAlign = 'center';
td.style.padding = '12px';
td.textContent = 'No overages.';
tr.appendChild(td);
tbody.appendChild(tr);
}
} catch (e) {
console.error('Error fetching overages:', e);
document.getElementById('messages').innerHTML = '<span style="color:red;">Error loading overages</span>';
}
}
setInterval(fetchOverages, 5000);
window.addEventListener('load', fetchOverages);
async function fetchStats() {
try {
const [cpu, ram, disk, uptime] = await Promise.all([
fetch('/cpu').then(res => res.json()),
fetch('/ram').then(res => res.json()),
fetch('/disk').then(res => res.json()),
fetch('/uptime').then(res => res.json())
]);
document.getElementById('cpu').textContent = cpu.cpu_percent + '%';
document.getElementById('ram').textContent = ram.percent + '%';
document.getElementById('disk').textContent = disk.percent + '%';
document.getElementById('uptime').textContent = uptime.uptime_seconds + ' s';
const sysInfo = await fetch('/info');
const data = await sysInfo.json();
// Format timestamps
data.uptime = formatTimestamp(data.uptime);
document.getElementById('cpu').textContent = data.cpu + '%';
document.getElementById('ram').textContent = data.ram + '%';
document.getElementById('disk').textContent = data.disk + '%';
document.getElementById('uptime').textContent = data.uptime + ' s';
} catch (e) {
console.error('Error fetching system stats:', e);
document.getElementById('cpu').textContent = 'Error';
document.getElementById('ram').textContent = 'Error';
document.getElementById('disk').textContent = 'Error';
@@ -81,89 +195,20 @@
}
return date.toLocaleString();
}
// Wall Messages CRUD
async function fetchMessages() {
const res = await fetch('/wall');
const messages = await res.json();
const ul = document.getElementById('messages');
ul.innerHTML = '';
messages.forEach(msg => {
const li = document.createElement('li');
li.style.display = 'flex';
li.style.justifyContent = 'space-between';
li.style.alignItems = 'center';
li.style.padding = '8px 0';
const span = document.createElement('span');
span.textContent = formatTimestamp(msg.timestamp) + " " + msg.text;
const editBtn = document.createElement('button');
editBtn.textContent = 'Edit';
editBtn.className = 'refresh-btn';
editBtn.style.background = '#ffa500';
editBtn.style.marginRight = '8px';
editBtn.onclick = () => editMessage(msg);
const delBtn = document.createElement('button');
delBtn.textContent = 'Delete';
delBtn.className = 'refresh-btn';
delBtn.style.background = '#d40000';
delBtn.onclick = () => deleteMessage(msg.id);
const btns = document.createElement('span');
btns.appendChild(editBtn);
btns.appendChild(delBtn);
li.appendChild(span);
li.appendChild(btns);
ul.appendChild(li);
});
}
async function addMessage(text) {
await fetch('/wall', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({text})
});
fetchMessages();
}
async function deleteMessage(id) {
await fetch(`/wall/${id}`, { method: 'DELETE' });
fetchMessages();
}
function editMessage(msg) {
const newText = prompt('Edit message:', msg.text);
if (newText !== null && newText.trim() !== '') {
updateMessage(msg.id, newText.trim());
}
}
async function updateMessage(id, text) {
await fetch(`/wall/${id}`, {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({text})
});
fetchMessages();
}
</script>
<script>
// --- Resource Limits Sliders ---
async function fetchLimits() {
try {
const res = await fetch('/limits');
const limits = await res.json();
document.getElementById('cpuLimit').value = limits.cpu;
document.getElementById('ramLimit').value = limits.ram;
document.getElementById('diskLimit').value = limits.disk;
document.getElementById('cpuLimitValue').textContent = limits.cpu + '%';
document.getElementById('ramLimitValue').textContent = limits.ram + '%';
document.getElementById('diskLimitValue').textContent = limits.disk + '%';
document.getElementById('cpuLimit').value = limits.cpu_threshold;
document.getElementById('ramLimit').value = limits.ram_threshold;
document.getElementById('diskLimit').value = limits.disk_threshold;
document.getElementById('cpuLimitValue').textContent = limits.cpu_threshold + '%';
document.getElementById('ramLimitValue').textContent = limits.ram_threshold + '%';
document.getElementById('diskLimitValue').textContent = limits.disk_threshold + '%';
} catch (e) {
console.error('Error fetching limits:', e);
// fallback: set to 50 if error
document.getElementById('cpuLimit').value = 50;
document.getElementById('ramLimit').value = 50;
@@ -174,17 +219,6 @@
}
}
async function updateLimits() {
const cpu = parseInt(document.getElementById('cpuLimit').value, 10);
const ram = parseInt(document.getElementById('ramLimit').value, 10);
const disk = parseInt(document.getElementById('diskLimit').value, 10);
await fetch('/limits', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ cpu, ram, disk })
});
}
function setupLimitSliders() {
['cpu', 'ram', 'disk'].forEach(resource => {
const slider = document.getElementById(resource + 'Limit');
@@ -198,21 +232,28 @@
});
}
document.getElementById('addMessageForm').onsubmit = function(e) {
e.preventDefault();
const input = document.getElementById('newMessage');
const text = input.value.trim();
if (text) {
addMessage(text);
input.value = '';
}
};
async function updateLimits() {
const cpu = parseInt(document.getElementById('cpuLimit').value, 10);
const ram = parseInt(document.getElementById('ramLimit').value, 10);
const disk = parseInt(document.getElementById('diskLimit').value, 10);
console.log(cpu, ram, disk);
const requestBody = JSON.stringify({
cpu_threshold: cpu,
ram_threshold: ram,
disk_threshold: disk
});
console.log(requestBody);
await fetch('/limits', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: requestBody
});
};
window.onload = function() {
fetchStats();
setInterval(fetchStats, 5000); // Fetch every 5 seconds
fetchMessages();
setInterval(fetchMessages, 5000); // Fetch messages every 5 seconds
fetchLimits();
setupLimitSliders();
setInterval(fetchLimits, 5000); // Fetch limits every 5 seconds