Админка: стек документов через absolute-позиционирование (без зазоров), компактные плитки

- Документы: сегменты сайт/бот позиционируются absolute от низа (bottom:0 и bottom:siPx),
  стыкуются вплотную — flex-подход давал зазор из-за нерезолвимых высот
- Плитки метрик ~вдвое ниже (padding 9px, val 20px); убрана плитка «Среднее на страницу»
  (среднее с/стр перенесено в подпись «Общее время обработки»)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
berkio_admin_gitea
2026-07-08 06:57:18 +00:00
parent 1bc90ce9f5
commit 5d226bdafc

View File

@@ -3035,11 +3035,11 @@ _ADMIN_HTML = """<!doctype html>
.top .sp{ flex:1; } .top .sp{ flex:1; }
button{ font:inherit; border:none; border-radius:10px; padding:8px 14px; background:var(--blue); color:#fff; cursor:pointer; } button{ font:inherit; border:none; border-radius:10px; padding:8px 14px; background:var(--blue); color:#fff; cursor:pointer; }
button.ghost{ background:#fff; color:var(--blue); border:1px solid var(--line); } button.ghost{ background:#fff; color:var(--blue); border:1px solid var(--line); }
.cards{ display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:12px; margin-bottom:20px; } .cards{ display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:10px; margin-bottom:18px; }
.card{ background:var(--card); border-radius:16px; padding:16px; } .card{ background:var(--card); border-radius:12px; padding:9px 14px; }
.card .lbl{ color:var(--sec); font-size:13px; margin-bottom:6px; } .card .lbl{ color:var(--sec); font-size:12px; margin-bottom:2px; }
.card .val{ font-size:26px; font-weight:600; } .card .val{ font-size:20px; font-weight:600; line-height:1.15; }
.card .sub{ color:var(--sec); font-size:12px; margin-top:4px; } .card .sub{ color:var(--sec); font-size:11px; margin-top:1px; }
section{ background:var(--card); border-radius:16px; padding:16px; margin-bottom:20px; overflow:hidden; } section{ background:var(--card); border-radius:16px; padding:16px; margin-bottom:20px; overflow:hidden; }
section h2{ font-size:16px; margin:0 0 12px; font-weight:600; } section h2{ font-size:16px; margin:0 0 12px; font-weight:600; }
.scroll{ overflow-x:auto; -webkit-overflow-scrolling:touch; } .scroll{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
@@ -3065,9 +3065,8 @@ _ADMIN_HTML = """<!doctype html>
.daychart-cap{ font-size:12px; color:var(--ink); margin-bottom:20px; display:flex; align-items:center; gap:10px; flex-wrap:wrap; } .daychart-cap{ font-size:12px; color:var(--ink); margin-bottom:20px; display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.dc-leg{ display:inline-flex; align-items:center; gap:4px; } .dc-leg{ display:inline-flex; align-items:center; gap:4px; }
.dc-leg i{ width:9px; height:9px; border-radius:2px; display:inline-block; } .dc-leg i{ width:9px; height:9px; border-radius:2px; display:inline-block; }
.b.stack{ background:transparent; display:flex; flex-direction:column; overflow:hidden; opacity:1; } .b.stack{ background:transparent; height:78px; overflow:visible; opacity:1; }
.b.stack .seg{ width:100%; flex:none; } .b.stack .seg{ position:absolute; left:0; right:0; }
.b.stack .seg.top{ border-bottom:1.5px solid var(--card); }
.muted{ color:var(--sec); } .muted{ color:var(--sec); }
#gate{ max-width:360px; margin:80px auto; background:#fff; border-radius:16px; padding:24px; text-align:center; } #gate{ max-width:360px; margin:80px auto; background:#fff; border-radius:16px; padding:24px; text-align:center; }
#gate input{ width:100%; padding:11px 12px; border:1px solid var(--line); border-radius:10px; font:inherit; margin:14px 0; } #gate input{ width:100%; padding:11px 12px; border:1px solid var(--line); border-radius:10px; font:inherit; margin:14px 0; }
@@ -3099,7 +3098,6 @@ _ADMIN_HTML = """<!doctype html>
<div class="card"><div class="lbl">Заходы сегодня</div><div class="val" id="m-vis">—</div><div class="sub" id="m-vis-sub"></div></div> <div class="card"><div class="lbl">Заходы сегодня</div><div class="val" id="m-vis">—</div><div class="sub" id="m-vis-sub"></div></div>
<div class="card"><div class="lbl">Документов обработано</div><div class="val" id="m-docs">—</div><div class="sub" id="m-docs-sub"></div></div> <div class="card"><div class="lbl">Документов обработано</div><div class="val" id="m-docs">—</div><div class="sub" id="m-docs-sub"></div></div>
<div class="card"><div class="lbl">Общее время обработки</div><div class="val" id="m-time">—</div><div class="sub" id="m-time-sub"></div></div> <div class="card"><div class="lbl">Общее время обработки</div><div class="val" id="m-time">—</div><div class="sub" id="m-time-sub"></div></div>
<div class="card"><div class="lbl">Среднее на страницу</div><div class="val" id="m-avg">—</div><div class="sub" id="m-avg-sub">время обработки 1 стр.</div></div>
</div> </div>
<section> <section>
@@ -3207,8 +3205,7 @@ _ADMIN_HTML = """<!doctype html>
document.getElementById('m-docs').textContent = (d.docs.total_count||0).toLocaleString('ru-RU'); document.getElementById('m-docs').textContent = (d.docs.total_count||0).toLocaleString('ru-RU');
document.getElementById('m-docs-sub').textContent = (d.docs.total_pages||0).toLocaleString('ru-RU') + ' стр. · ' + size(d.docs.total_result_mb); document.getElementById('m-docs-sub').textContent = (d.docs.total_pages||0).toLocaleString('ru-RU') + ' стр. · ' + size(d.docs.total_result_mb);
document.getElementById('m-time').textContent = dur(d.docs.total_seconds); document.getElementById('m-time').textContent = dur(d.docs.total_seconds);
document.getElementById('m-time-sub').textContent = 'суммарно по всем файлам'; document.getElementById('m-time-sub').textContent = 'всего · ~' + (d.docs.avg_page_seconds||0).toFixed(1) + ' с/стр';
document.getElementById('m-avg').textContent = (d.docs.avg_page_seconds||0).toFixed(1) + ' с';
// Подписки // Подписки
var subs = d.subs.list || []; var subs = d.subs.list || [];
@@ -3233,17 +3230,20 @@ _ADMIN_HTML = """<!doctype html>
' (уник. ' + (d.visits.unique_total||0).toLocaleString('ru-RU') + ')'; ' (уник. ' + (d.visits.unique_total||0).toLocaleString('ru-RU') + ')';
// 2) Документы — стек сайт (низ, синий) + бот (верх, фиолетовый). // 2) Документы — стек сайт (низ, синий) + бот (верх, фиолетовый).
// Высоты сегментов В ПИКСЕЛЯХ (высота графика = 78px, см. .bars) — иначе // Абсолютное позиционирование от низа (px): сегменты стыкуются вплотную,
// вложенные проценты во flex не резолвятся и между сегментами появляется зазор. // без flex-зазоров. Высота графика = 78px (см. .bars).
var mD = barMax(function(x){return (x.files_site||0)+(x.files_bot||0);}); var mD = barMax(function(x){return (x.files_site||0)+(x.files_bot||0);});
var CH = 78; var CH = 78;
var totSite=0, totBot=0; var totSite=0, totBot=0;
document.getElementById('bars-docs').innerHTML = dl.length ? dl.map(function(x){ document.getElementById('bars-docs').innerHTML = dl.length ? dl.map(function(x){
var si=x.files_site||0, bo=x.files_bot||0, tot=si+bo; totSite+=si; totBot+=bo; var si=x.files_site||0, bo=x.files_bot||0, tot=si+bo; totSite+=si; totBot+=bo;
var siPx = si>0 ? Math.max(2, Math.round(si/mD*CH)) : 0;
var boPx = bo>0 ? Math.max(2, Math.round(bo/mD*CH)) : 0;
var segs=''; var segs='';
if(bo>0) segs += '<div class="seg'+(si>0?' top':'')+'" style="height:'+Math.max(2,Math.round(bo/mD*CH))+'px;background:#5856d6"></div>'; if(si>0) segs += '<div class="seg" style="bottom:0;height:'+siPx+'px;background:#007AFF'+(bo>0?'':';border-radius:4px 4px 0 0')+'"></div>';
if(si>0) segs += '<div class="seg" style="height:'+Math.max(2,Math.round(si/mD*CH))+'px;background:#007AFF"></div>'; if(bo>0) segs += '<div class="seg" style="bottom:'+siPx+'px;height:'+boPx+'px;background:#5856d6;border-radius:4px 4px 0 0'+(si>0?';border-bottom:1.5px solid var(--card)':'')+'"></div>';
return '<div class="b stack" title="'+x.day+': '+tot+' документов (сайт '+si+', бот '+bo+')"><b>'+(tot||'')+'</b>'+segs+'<span>'+dd(x)+'</span></div>'; var lbl = tot ? '<b style="top:auto;bottom:'+(siPx+boPx+2)+'px">'+tot+'</b>' : '';
return '<div class="b stack" title="'+x.day+': '+tot+' документов (сайт '+si+', бот '+bo+')">'+lbl+segs+'<span>'+dd(x)+'</span></div>';
}).join('') : emptyBars; }).join('') : emptyBars;
document.getElementById('docs-cap').textContent = '· сайт ' + totSite + ' / бот ' + totBot + ' за 14 дн.'; document.getElementById('docs-cap').textContent = '· сайт ' + totSite + ' / бот ' + totBot + ' за 14 дн.';