Add Valkey/Redis cache visualization and API autoloading for graphical inspection
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Valkey/Redis Cache Visualization</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; background: #f8fafc; margin: 0; padding: 2em; }
|
||||
h1 { color: #2563eb; }
|
||||
table { border-collapse: collapse; width: 100%; background: #fff; }
|
||||
th, td { border: 1px solid #e5e7eb; padding: 0.5em 1em; }
|
||||
th { background: #f1f5f9; }
|
||||
tr:nth-child(even) { background: #f9fafb; }
|
||||
.json { font-family: monospace; font-size: 0.95em; white-space: pre; }
|
||||
.expand { cursor: pointer; color: #2563eb; text-decoration: underline; }
|
||||
.search { margin-bottom: 1em; padding: 0.5em; width: 300px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Valkey/Redis Cache Visualization</h1>
|
||||
<input class="search" type="text" id="search" placeholder="Search by key or value..." />
|
||||
<table id="cacheTable">
|
||||
<thead>
|
||||
<tr><th>Key</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<script>
|
||||
let cacheData = [];
|
||||
function renderTable(data) {
|
||||
const tbody = document.querySelector('#cacheTable tbody');
|
||||
tbody.innerHTML = '';
|
||||
for (const { key, value } of data) {
|
||||
const tr = document.createElement('tr');
|
||||
const tdKey = document.createElement('td');
|
||||
tdKey.textContent = key;
|
||||
const tdValue = document.createElement('td');
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
const btn = document.createElement('span');
|
||||
btn.textContent = '[expand]';
|
||||
btn.className = 'expand';
|
||||
btn.onclick = () => {
|
||||
btn.outerHTML = `<div class='json'>${JSON.stringify(value, null, 2)}</div>`;
|
||||
};
|
||||
tdValue.appendChild(btn);
|
||||
} else {
|
||||
tdValue.textContent = String(value);
|
||||
}
|
||||
tr.appendChild(tdKey);
|
||||
tr.appendChild(tdValue);
|
||||
tbody.appendChild(tr);
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch cache data from API
|
||||
async function loadCache() {
|
||||
try {
|
||||
const res = await fetch('http://localhost:3006/api/cache');
|
||||
cacheData = await res.json();
|
||||
renderTable(cacheData);
|
||||
} catch (err) {
|
||||
document.querySelector('#cacheTable tbody').innerHTML = `<tr><td colspan='2' style='color:#b91c1c'>Failed to load cache data: ${err}</td></tr>`;
|
||||
}
|
||||
}
|
||||
|
||||
// Search functionality
|
||||
document.getElementById('search').addEventListener('input', function() {
|
||||
const q = this.value.toLowerCase();
|
||||
renderTable(cacheData.filter(({key, value}) =>
|
||||
key.toLowerCase().includes(q) || JSON.stringify(value).toLowerCase().includes(q)
|
||||
));
|
||||
});
|
||||
|
||||
// Initial load
|
||||
loadCache();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user