Analytics: make the pass, partial and fail indicators clickable

The three verdict cards on /analytics now open the same dialog as the https/ssh
cards, with the addresses of the run that got this verdict (CSV and copy
included). New list kinds verdict_pass, verdict_partial and verdict_fail in
GET /admin/analytics/runs/{id}/lists/{kind}: address, subnet, validator,
egress and ingress "ok of all", checks stored of expected; partial adds the
reason, the same names as the "Why partial" block. Cancelled addresses are not
listed; the row count equals summary.pass/partial/fail. The fail card stays
inert at zero. addr.incomplete() is shared by the list and the report.

Docs, plan and summary in docs/changes/.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ayurishchevandClaude Sonnet 5.5 committed 2026-10-04 10:00:39 +03:00
1 parent e95b5eb7d5
commit 2f038f8362
15 files changed
+294 -14

No files matched your search

+24 -4
View File
@@ -23,13 +23,13 @@
/* ---- indicators ---- */
function renderKpis() {
var late = Q.late_failed_checks_at_pass;
var late = Q.late_failed_checks_at_pass, GO = ' <span class="an-go">список →</span>';
var tiles = [
['Адресов', fmt(S.addresses), 'последний цикл каждого адреса', '', ''],
['pass', fmt(S.pass), pct(S.pass, S.addresses) + '% адресов', '<span class="an-tag an-t-ok">успех</span>', ''],
['partial', fmt(S.partial), pct(S.partial, S.addresses) + '% адресов', '<span class="an-tag an-t-warn">частично</span>', ''],
['pass', fmt(S.pass), pct(S.pass, S.addresses) + '% адресов', '<span class="an-tag an-t-ok">успех</span>' + GO, 'verdict_pass'],
['partial', fmt(S.partial), pct(S.partial, S.addresses) + '% адресов', '<span class="an-tag an-t-warn">частично</span>' + GO, 'verdict_partial'],
['fail', fmt(S.fail), S.fail ? pct(S.fail, S.addresses) + '% адресов' : 'ни одной полностью проваленной',
S.fail ? '<span class="an-tag an-t-bad">провал</span>' : '<span class="an-tag an-t-n">нет</span>', ''],
S.fail ? '<span class="an-tag an-t-bad">провал</span>' + GO : '<span class="an-tag an-t-n">нет</span>', S.fail ? 'verdict_fail' : ''],
['Egress OK', pct1(S.egress_ok, S.addresses) + '%', 'все egress-проверки адреса успешны', '', ''],
['Ingress OK', pct1(S.ingress_ok, S.addresses) + '%', 'все ingress-проверки адреса успешны', '', ''],
['Egress https: есть провалы', fmt(S.egress_https_any_failed), pct1(S.egress_https_any_failed, S.addresses) + '% адресов, хотя бы одна цель недоступна',
@@ -168,7 +168,27 @@
};
function statusVal(v) { return String(v).indexOf('после') >= 0 ? 'Результат пришёл после вердикта адреса и в него не вошёл.' : 'Результат пришёл до вердикта и учтён в нём.'; }
var VERDICT_NOTE = ' Это вердикт адреса, который система выставила при агрегации, а не итог всех проверок: после него могли прийти ещё результаты, поэтому у адреса pass бывают проваленные проверки. Столбцы Egress и Ingress показывают фактические проверки адреса.';
var VERDICT_HINTS = {
2: 'Валидатор, с которого шли egress-проверки адреса. «—» — у адреса нет https-проверок.',
3: 'Сколько egress-проверок адреса успешно из всех записанных в цикле. «—» — egress-проверок нет.',
4: 'Сколько ingress-проверок адреса успешно из всех записанных в цикле (со всех площадок и всех типов). «—» — ingress-проверок нет.',
5: 'Сколько проверок записано в цикле из ожидаемых. Меньше ожидаемого значит, что часть результатов не пришла (неполный набор). Если ожидаемое число неизвестно, показано только записанное.'
};
function verdictList(title, note, reason) {
var hints = {};
Object.keys(VERDICT_HINTS).forEach(function (k) { hints[k] = VERDICT_HINTS[k]; });
if (reason) hints[6] = 'Что не так у адреса: провалены egress-проверки, ingress-проверки или не хватает результатов (неполный набор). Те же названия, что в блоке «Почему partial».';
return { title: title, note: note + VERDICT_NOTE, hints: hints };
}
var LISTS = {
verdict_pass: verdictList('Адреса с вердиктом pass',
'Вердикт pass: адрес за последний цикл запуска получил успех по всем проверкам, полученным к моменту агрегации.'),
verdict_partial: verdictList('Адреса с вердиктом partial',
'Вердикт partial: часть проверок адреса провалена или результатов не хватило.', true),
verdict_fail: verdictList('Адреса с вердиктом fail',
'Вердикт fail: все проверки адреса провалены.'),
egress_https_any: {
title: 'Egress https: адреса с проваленными проверками',
note: 'Хотя бы одна egress-проверка https адреса провалена в последнем цикле запуска.',