Commit 17ce6867 authored by Vitaly Lipatov's avatar Vitaly Lipatov

router: show last applied timestamp on main page, remove heavy active routes section

Replace the full active routes listing with a lightweight timestamp fetched from /api/active, shown inline in the footer note. Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent c1be8f26
......@@ -248,17 +248,6 @@ HTML_PAGE = """\
.status.ok { display: block; background: #d4edda; color: #155724; }
.status.err { display: block; background: #f8d7da; color: #721c24; }
.note { text-align: center; color: #999; font-size: 0.8em; margin-top: 16px; }
.active-section { margin-top: 24px; }
.active-section h2 { font-size: 1.2em; margin-bottom: 12px; }
.active-group { background: #fff; border-radius: 6px; padding: 12px 16px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1); margin-bottom: 12px; }
.active-group summary { cursor: pointer; font-weight: 600; font-size: 1em;
padding: 4px 0; }
.active-group summary .count { color: #999; font-weight: normal; font-size: 0.85em; }
.active-list-name { color: #666; font-size: 0.85em; margin-top: 8px; margin-bottom: 2px; }
.active-entries { font-family: monospace; font-size: 0.85em; color: #555;
line-height: 1.6; column-count: 2; column-gap: 24px; }
@media (max-width: 600px) { .active-entries { column-count: 1; } }
</style>
</head>
<body>
......@@ -283,10 +272,6 @@ HTML_PAGE = """\
</div>
</div>
<p class="note">Изменения применятся в течение 5 минут · <a href="/swagger">API docs</a></p>
<div class="active-section">
<h2>Действующие правила <span id="active-updated" class="subtitle"></span></h2>
<div id="active-routes"></div>
</div>
<script>
const $ = id => document.getElementById(id);
......@@ -398,65 +383,18 @@ async function moveEntry(domain, from, to) {
refresh();
}
async function refreshActive() {
try {
const d = await api('active');
const el = $('active-routes');
el.textContent = '';
if (d.updated) {
const ts = new Date(d.updated * 1000);
$('active-updated').textContent = 'обновлено ' + ts.toLocaleString('ru');
}
const groups = Object.keys(d.groups || {}).sort();
if (!groups.length) {
const p = document.createElement('div');
p.className = 'empty';
p.textContent = 'Нет данных (ожидание первого цикла route-update)';
el.appendChild(p);
return;
}
for (const group of groups) {
const lists = d.groups[group];
let totalCount = 0;
for (const v of Object.values(lists))
totalCount += Array.isArray(v) ? v.length : v.count;
const details = document.createElement('details');
details.className = 'active-group';
const summary = document.createElement('summary');
const nameSpan = document.createElement('span');
nameSpan.textContent = group;
const countSpan = document.createElement('span');
countSpan.className = 'count';
countSpan.textContent = ' (' + totalCount + ')';
summary.appendChild(nameSpan);
summary.appendChild(countSpan);
details.appendChild(summary);
for (const [fname, entries] of Object.entries(lists)) {
const h = document.createElement('div');
h.className = 'active-list-name';
h.textContent = fname;
details.appendChild(h);
const div = document.createElement('div');
div.className = 'active-entries';
if (Array.isArray(entries)) {
div.textContent = entries.join(', ');
} else {
div.textContent = entries.count + ' записей (IP-список)';
div.style.fontStyle = 'italic';
div.style.color = '#999';
}
details.appendChild(div);
}
el.appendChild(details);
}
} catch (e) { /* ignore — file may not exist yet */ }
}
$('domain').addEventListener('keydown', e => {
if (e.key === 'Enter') addEntry('bypass');
});
refresh();
fetch('/api/active').then(r=>r.json()).then(d=>{
if(d.updated){
const ts=new Date(d.updated*1000);
document.querySelector('.note').insertAdjacentHTML('beforeend',
' · правила применены '+ts.toLocaleString('ru'));
}
}).catch(()=>{});
</script>
</body>
</html>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment