Show check-type usage and stats on the target groups dashboard page
Each target group's relationship to the check types that reference it was previously invisible without cross-referencing /check-types by hand. handleTargetsPage/renderTargetsTable now resolve that server-side via loadTargetsPage (group -> referencing check types, enabled or not) and render it as a status pill per group, plus a stats row (group count, total targets, check types using them, unused groups) kept live via an out-of-band swap on every create/update/delete. Also auto-sizes the targets textarea as you type (targets.html), and lets the stat-card grid collapse to however many state cards actually exist instead of leaving empty background where a fixed repeat(6, ...) had no card to fill. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
95f8066eed
commit
792b7fbb84
4 files changed
+244
-18
No files matched your search
@@ -264,7 +264,7 @@ nav.nav-groups { display: flex; flex-direction: column; gap: 1px; }
|
||||
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
|
||||
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
|
||||
|
||||
.main { padding: 22px 26px 60px; max-width: 1180px; }
|
||||
.main { padding: 22px 26px 60px; max-width: 1180px; margin-inline: auto; }
|
||||
.topbar {
|
||||
display: flex; align-items: baseline; justify-content: space-between;
|
||||
margin-bottom: 18px; flex-wrap: wrap; gap: 10px;
|
||||
@@ -273,7 +273,13 @@ nav.nav-groups { display: flex; flex-direction: column; gap: 1px; }
|
||||
|
||||
/* ---------- stat cards ---------- */
|
||||
.stat-grid {
|
||||
display: grid; grid-template-columns: repeat(6, 1fr);
|
||||
/* auto-fit instead of a fixed repeat(6, ...): the state histogram this
|
||||
drives is a variable-length map (whichever ip_queue states are
|
||||
actually present), so a fixed column count left visible empty
|
||||
background showing through the unused grid tracks whenever fewer
|
||||
than 6 cards exist. auto-fit collapses empty tracks and lets the
|
||||
real cards stretch to fill the row instead. */
|
||||
display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
gap: 1px; background: var(--border);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
@@ -475,7 +481,6 @@ code.inline { font-family: var(--font-mono); background: var(--surface-alt); bor
|
||||
display: grid; place-items: center; cursor: pointer; flex-shrink: 0;
|
||||
}
|
||||
.main { padding: 16px 14px 50px; }
|
||||
.stat-grid { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
@@ -496,3 +501,46 @@ code.inline { font-family: var(--font-mono); background: var(--surface-alt); bor
|
||||
}
|
||||
.actions { justify-content: flex-start; margin-top: 6px; }
|
||||
}
|
||||
|
||||
/* ---------- targets page: group summary + usage ---------- */
|
||||
|
||||
/* 4-card variant of .stat-grid for pages whose summary row isn't the
|
||||
dynamic ips_by_state histogram (which wants 6 columns). */
|
||||
.stat-grid.cols-4 { grid-template-columns: repeat(4, 1fr); }
|
||||
@media (max-width: 900px) { .stat-grid.cols-4 { grid-template-columns: repeat(2, 1fr); } }
|
||||
|
||||
/* Neutral data token for listing individual targets inline — distinct
|
||||
from .pill (which always carries a status meaning via its color + dot):
|
||||
a chip is just a value, not a state. */
|
||||
.chip-list { display: flex; flex-wrap: wrap; gap: 5px; max-width: 460px; }
|
||||
.chip {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11.5px;
|
||||
padding: 2px 7px;
|
||||
border-radius: var(--radius-xs);
|
||||
background: var(--surface-alt);
|
||||
border: 1px solid var(--border-soft);
|
||||
color: var(--text-muted);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Row group name + target count, stacked. */
|
||||
.group-name { display: flex; flex-direction: column; gap: 2px; }
|
||||
.group-name .count { font-size: 11px; color: var(--text-faint); font-weight: 400; text-transform: none; letter-spacing: 0; font-family: var(--font-ui); }
|
||||
|
||||
/* "Used by" cell — wraps its pills with a small gap, same idiom as
|
||||
chip-list, kept separate since these ARE status-colored .pill elements. */
|
||||
.used-by { display: flex; flex-wrap: wrap; gap: 4px; }
|
||||
|
||||
/* Inline edit row, toggled open by the "Изменить" button — collapses by
|
||||
default so the table stays scannable instead of showing N always-open
|
||||
textareas at once. */
|
||||
tr.edit-row td { background: var(--surface-alt); padding: 14px 16px; }
|
||||
tr.edit-row textarea { flex: 1 1 auto; }
|
||||
|
||||
/* Auto-growing textarea (new-group form + per-row edit forms above) —
|
||||
stretches with content instead of showing an internal scrollbar
|
||||
immediately; only caps out (and starts scrolling) past ~20 lines.
|
||||
Height is set by JS (see templates/targets.html), computed from the
|
||||
field's own line-height, so it stays correct if font-size ever changes. */
|
||||
textarea.autosize { overflow-y: hidden; resize: none; }
|
||||
Reference in new issue
Block a user