diff --git a/VERSION b/VERSION index ccefc02..202169a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.137 +0.0.138 diff --git a/frontend/settings.html b/frontend/settings.html index 4cad582..d5ae907 100644 --- a/frontend/settings.html +++ b/frontend/settings.html @@ -47,7 +47,7 @@ - +
IDКамераIPПотокиВклЗаписьХранилищеСтатус
IDКамераIPПотокиВклЗаписьХранилищеСтатус
diff --git a/frontend/static/app.js b/frontend/static/app.js index d124b58..bed7e84 100644 --- a/frontend/static/app.js +++ b/frontend/static/app.js @@ -1257,6 +1257,12 @@ const CamSettings = { `` + `` + `` + + `` + + `` + + (cam + ? ` ` + + `` + : "") + `` ); }, @@ -1328,7 +1334,7 @@ const CamSettings = { const v = (x) => this.esc(x); const isEdit = !!cam; return ( - `` + + `` + `
` + `` + `` + @@ -1444,7 +1450,8 @@ const CamSettings = { `` + `` + `` + - `${statusCell}`; + `${statusCell}` + + ``; tb.appendChild(tr); } else { tr.className = "slot-empty"; @@ -1452,7 +1459,8 @@ const CamSettings = { tr.innerHTML = `${i + 1}` + `——————` + - `пусто`; + `пусто` + + ``; tb.appendChild(tr); } } @@ -1473,9 +1481,14 @@ const CamSettings = { } else if (act === "delete") { this.remove(id, this.byId[id] ? this.byId[id].name : id); } else if (act === "restart") { - btn.disabled = true; btn.textContent = "…"; + const prev = btn.textContent; btn.disabled = true; btn.textContent = "…"; await post(`/api/cameras/${id}/restart`); - setTimeout(() => this.load(), 1500); + if (this.bulk) { // в массовом режиме строки не перерисовываем (правки не теряем) + btn.textContent = "✓"; + setTimeout(() => { btn.textContent = prev; btn.disabled = false; }, 1500); + } else { + setTimeout(() => this.load(), 1500); + } } else if (act === "log") { const box = document.getElementById("log-" + id); if (!box.hidden) { box.hidden = true; return; } diff --git a/frontend/static/style.css b/frontend/static/style.css index a9436a8..73176bc 100644 --- a/frontend/static/style.css +++ b/frontend/static/style.css @@ -425,9 +425,25 @@ table.cams th, table.cams td { table.cams th { color: var(--text-dim); font-weight: 500; font-size: 11px; padding: 4px 10px; } table.cams td.actions { white-space: nowrap; text-align: right; } table.cams tr.slot-empty td { opacity: .5; } -/* камеры: жёстко фиксированная высота строки 22px (плотная таблица) */ +/* камеры: жёстко фиксированная высота строки 22px независимо от контролов. + line-height:1 + контролы по центру и ниже 22px → строки не распирает. */ table.cams.cams-fixed td, table.cams.cams-fixed th { - height: 22px; padding-top: 0; padding-bottom: 0; line-height: 22px; + height: 22px; padding-top: 0; padding-bottom: 0; line-height: 1; +} +table.cams.cams-fixed td > * { vertical-align: middle; } +/* тумблеры «Вкл»/«Запись» в строке — компактные (30×16) */ +table.cams.cams-fixed td input[type="checkbox"] { + width: 30px; height: 16px; border-radius: 8px; +} +table.cams.cams-fixed td input[type="checkbox"]::before { width: 12px; height: 12px; top: 1px; left: 1px; } +table.cams.cams-fixed td input[type="checkbox"]:checked::before { transform: translateX(14px); } +/* селекты и инпуты в строке — на 2px ниже строки, по центру */ +table.cams.cams-fixed td select.stor-sel, +table.cams.cams-fixed td select.cell-sel, +table.cams.cams-fixed td input.cell-in { height: 20px; } +/* кнопки действий ⟳/✕ (режим редактирования) — компактные */ +table.cams.cams-fixed td.actions button { + height: 20px; padding: 0 6px; font-size: 13px; line-height: 1; } /* ── Инлайн-редактор строки (вместо всплывающего окна) ── */