2

Use compact SVG icons for requests actions

This commit is contained in:
2026-03-12 21:37:07 +01:00
parent 4de8bb9808
commit d4fe3f381d
2 changed files with 16 additions and 5 deletions

View File

@@ -986,9 +986,10 @@ const queryLogHTML = `<!doctype html>
.state-pill.review { background: #78350f; }
.state-pill.allowed { background: #14532d; }
.state-pill.observed { background: #1e293b; }
.action-icon { width: 1.9rem; height: 1.9rem; padding: 0; border-radius: .5rem; display: inline-flex; align-items: center; justify-content: center; border: 0; cursor: pointer; font-size: .95rem; }
.action-icon.block { background: #dc2626; color: white; }
.action-icon.unblock { background: #475569; color: white; }
.action-icon { width: 1.55rem; height: 1.55rem; min-width: 1.55rem; padding: 0; border-radius: .45rem; display: inline-flex; align-items: center; justify-content: center; border: 1px solid #334155; cursor: pointer; line-height: 1; vertical-align: middle; background: #0f172a; color: #e2e8f0; }
.action-icon svg { width: .9rem; height: .9rem; display: block; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.action-icon.block { background: #3f0b14; border-color: #7f1d1d; color: #fecaca; }
.action-icon.unblock { background: #172033; border-color: #334155; color: #cbd5e1; }
.tabulator { background: transparent; border: 0; font-size: .92rem; width: 100% !important; }
.tabulator .tabulator-header { background: #0f172a; border-bottom: 1px solid #334155; }
.tabulator .tabulator-header .tabulator-header-contents { width: 100% !important; }
@@ -1296,13 +1297,20 @@ const queryLogHTML = `<!doctype html>
return '<span class="bot-chip ' + escapeHtml(visual.className) + ' ' + statusClass + '" title="' + escapeHtml(title) + '">' + escapeHtml(visual.short) + '</span>';
}
function actionIconSVG(kind) {
if (kind === 'unblock') {
return '<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="5" y="11" width="14" height="9" rx="2"></rect><path d="M9 11V8a3 3 0 0 1 5.8-1.1"></path><path d="M16 4.5a3 3 0 0 1 1 2.2"></path></svg>';
}
return '<svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="8"></circle><path d="M8.5 8.5l7 7"></path><path d="M15.5 8.5l-7 7"></path></svg>';
}
function renderActions(item) {
const actions = item.actions || {};
if (actions.can_unblock) {
return '<button class="action-icon unblock" data-ip="' + escapeHtml(item.client_ip) + '" title="Unblock this IP" aria-label="Unblock this IP" onclick="sendAction(this.dataset.ip, \'unblock\', \'Reason for manual unblock\')">🔓</button>';
return '<button class="action-icon unblock" data-ip="' + escapeHtml(item.client_ip) + '" title="Unblock this IP" aria-label="Unblock this IP" onclick="sendAction(this.dataset.ip, \'unblock\', \'Reason for manual unblock\')">' + actionIconSVG('unblock') + '</button>';
}
if (actions.can_block) {
return '<button class="action-icon block" data-ip="' + escapeHtml(item.client_ip) + '" title="Block this IP" aria-label="Block this IP" onclick="sendAction(this.dataset.ip, \'block\', \'Reason for manual block\')"></button>';
return '<button class="action-icon block" data-ip="' + escapeHtml(item.client_ip) + '" title="Block this IP" aria-label="Block this IP" onclick="sendAction(this.dataset.ip, \'block\', \'Reason for manual block\')">' + actionIconSVG('block') + '</button>';
}
return '<span class="muted">—</span>';
}